当我需要运行服务器端代码时,我如何响应按钮的单击(不提交页面)?

How can I respond to the click of a button (without a submission of the page) when I need to run server-side code?

本文关键字:单击 按钮 提交 响应 代码 服务器端 运行 何响应      更新时间:2023-09-26

这是我ASP的第22条军规。. NET (Sharepoint) WebPart/page。我需要响应按钮单击,但这样做需要代码是客户端(jQuery),因为服务器端/代码隐藏似乎只对"提交"过程可用,我不想在这种情况下提交页面。

为了更清楚,这是我可以做的,有一个按钮(一个HtmlButton,更准确地说),并响应点击它,而不提交表单:

服务器端(c#):

HtmlButton btnAddFoapalRow = null;
. . .
btnAddFoapalRow = new HtmlButton();
btnAddFoapalRow.Attributes["type"] = "button";
btnAddFoapalRow.InnerHtml = "+"; 
btnAddFoapalRow.ID = "btnAddFoapalRow";
this.Controls.Add(btnAddFoapalRow);

客户端(jQuery):

$(document).on("click", '[id$=btnAddFoapalRow]', function (e) {
    ... script elided for brevity
});

我可以在服务器端(c#中)为"提交"按钮完成这一切,像这样:

Button btnSave = new Button();
btnSave.Text = "Save";
btnSave.Click += new EventHandler(btnSave_Click);
this.Controls.Add(btnSave);
. . .
private void btnSave_Click(object sender, EventArgs e)
{
    . . . code elided for brevity
}

但问题的关键是,我需要响应一个按钮点击而不提交表单,但然后运行一些代码在服务器端。我可以在jQuery中满足第一个要求(如上面的HtmlButton btnAddFoapalRow所示),但我最终需要调用一些c#代码来响应点击-我需要在服务器端执行一个操作。

所以我的问题是:我如何从客户端代码"戳"服务器端代码"唤醒并调用这个(某些)函数"?

也许我可以更新我在c#中创建的变量(HiddenField),像这样:

HiddenField PDFGenBtnClicked = null;
. . .
PDFGenBtnClicked = new HiddenField();
PDFGenBtnClicked.ID = "pdfgenbtnclicked";
PDFGenBtnClicked.Value = "no";
this.Controls.Add(PDFGenBtnClicked);

…从jQuery,像这样:

$(document).on("click", '[id$=btnGeneratePDF]', function () {
    $('[id$=pdfgenbtnclicked]').val("yes");
});

. .然后在服务器端有这样的代码来启动方法的调用:

if (PDFGenBtnClicked.Value == "yes")
{
    GeneratePDF(listOfListItems);
}

…但是我怎样才能调用这(最后)位代码呢?我可以在页面上放一个计时器,让它检查PDFGenBtnClicked的状态吗?偶尔的价值?这可能是可能的,但几乎可以肯定是戈德伯格式的。

谁有更好的主意?

更新

理论上(我认为!)这应该工作(非ajax方式从客户端代码间接运行服务器端代码):

0)创建定时器

private Timer tmr = null;
1)创建"生成PDF"按钮和定时器:
btnGeneratePDF = new HtmlButton();
btnGeneratePDF.Attributes["type"] = "button";
btnGeneratePDF.InnerHtml = "Generate PDF";
btnGeneratePDF.ID = "btnGeneratePDF ";
this.Controls.Add(btnGeneratePDF);
tmr = new Timer();
tmr.Interval = 3000; // three seconds
tmr.Tick += TickHandler; 
tmr.Enabled = true;

2)当Timer触发时调用该方法:

private void TickHandler(object sender, object e)
{
    GeneratePDF(listOfListItems);
}

3)如果用户选择了"生成PDF"按钮,运行代码:

private void GeneratePDF(List<ListColumns> listOfListItems)
{
    if (PDFGenBtnClicked.Value != "yes")
    {
        return;
    }
    tmr.Enabled = false; // only run this once, after val has changed to "yes" by the user clicking the "btnGeneratePDF" button (set from "no" to "yes" in jQuery's response to the clicking of the button)
    . . .

但是,我在GeneratePDF()的第一行上有一个断点,而且我没有到达它,请忽略它。

更新2

我甚至为init添加了另一个事件处理程序:

tmr.Tick += TickHandler;
tmr.Init += InitHandler;
tmr.Enabled = true;
message.Text = "Converting the data to a PDF file has been successful";

(我确实看到消息Text,尽管它不是真的)。

在两个方法中都有断点

private void TickHandler(object sender, object e)
{
    GeneratePDF(listOfListItems);
}
private void InitHandler(object sender, object e)
{
    GeneratePDF(listOfListItems);
}

…两者都没有达到。为什么不呢?从理论上讲,这似乎是可行的……(我知道,一切都在理论上行得通)

你想要完成的事情可以通过webservices和ajax来完成。

Jquery。Ajax可用于向web服务(或网页,或其他)发送请求。下面是我的一个网站上的例子:

$.ajax({
    type: "POST",
    contentType: "application/json; charset=utf-8",
    url: "FoamServices.asmx/GetFoamNames",
    data: "{'term':'" + $("#txtFoamName").val() + "'}",
    success: function (data) {
        //whatever you want to do with the data
    },
    error: function (result) {
        alert("Error");
    }
    });
关于这个例子的更多信息可以在Jquery中找到。ajax网站,但它的要点是,我有一个web服务设置,泡沫服务。asmx和该web服务中的GetFoamNames方法。GetFoamNames接受"term"作为参数。成功后,我将从该网站获取数据并执行我想要的操作(检查真值,将其注入页面,等等)。 在服务器端,这是我的webservice:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

[System.Web.Script.Services.ScriptService]
public class FoamServices : System.Web.Services.WebService {
public FoamServices () {
    //Uncomment the following line if using designed components 
    //InitializeComponent(); 
}
[WebMethod]
public string[] GetFoamNames(string term) {
    List<Foam> foams = Foam.Read(term);
    string[] foamNames = new string[foams.Count];
    for(int i = 0; i < foams.Count; i++)
    {
        foamNames[i] = foams[i].FoamName;
    }
    return foamNames;
}
}                        

这是一个webservice的基本设置,它也允许它接受来自javascript (JQuery)请求的参数。

我的服务所做的是在数据库中查询一个搜索词并返回结果。这是自动完成JQuery框的基本设置。

你可以根据自己的喜好进行调整,或者你也可以使用ajax来调用网页而不是webservice,并让它做一些事情。

希望这对你有帮助!

对你的问题的简短回答是,你必须使用ajax, jQuery有一些关于使用它的信息- https://learn.jquery.com/ajax/。

更长的答案是你需要做这样的事情:

$(document).on("click", '[id$=btnGeneratePDF]', function () {
    $.get('/some/route/', function(result) {
        //do something with the response, or not depending on your needs
    }
});

我不熟悉Sharepoint,所以我不能在这方面提供任何帮助,但基本的是,你需要创建一个新的页面,触发你的PDF生成和使用ajax访问它,然后以任何合适的方式处理结果

我唯一的建议是,如果您只想刷新页面的一部分而不进行完整的回发,请使用AJAX、回调或更新面板。更新面板非常简单,但取决于你的按钮实际做什么可能不是最好的选择。为了以防万一,这里有一个例子

 <asp:ScriptManager runat="server" ID="sm">
 </asp:ScriptManager>
 <asp:updatepanel runat="server">
     <ContentTemplate>
         <asp:button id="YourButton" runat="server" Text="clickme" onclick="function" />
     </ContentTemplate>
 </asp:updatepanel>

这不会导致完整的回发,而且IMO比AJAX更简单,但就像我说的,可能不是最合适的解决方案,这取决于您的确切情况

这里有一个链接,如果你想阅读它,你可能会从MSDN网站上找到有用的。