【问题标题】:Manually making AJAX calls in ASP.NET and C#在 ASP.NET 和 C# 中手动进行 AJAX 调用
【发布时间】:2011-01-17 11:00:58
【问题描述】:

我想在 ASP.NET 中编写自己的 AJAX,而不是使用 ASP.NET ScriptManager 等。

为什么?我喜欢手动做一些事情,并且知道事情是如何从内部工作的,所以我只想为自己做这件事。

所以我的问题是,在我进行 AJAX 调用之后:

var ajaxCall = new XMLHttpRequest();
....
ajaxCall.send(null)

我如何在 C# 中添加(或不添加)Page_Load,以便它侦听并返回一个字符串。

【问题讨论】:

    标签: c# asp.net ajax xmlhttprequest


    【解决方案1】:

    +1 为你自己做事 - 我想知道在使用为我做事的框架之前我可以自己做事,所以如果它成功了,我大致知道如何开始修复它。

    无论如何,你的问题。只需使用 ASP.NET 或 Response.Write 正常输出数据。如果您正在执行 POST 请求,您可以使用 if (Page.IsPostBack) 在 Page_Load 中检查这一点。请记住,通常您只会发送部分页面的数据,而不是整个页面本身,所以您不需要<html><head><body> 标签。

    当我之前在 ASP.NET 网站上看到过这种情况时,AJAX 调用使用了单独的页面(例如 index.aspx = 普通站点,index-ajax.aspx = ajaxified 页面组件。)

    if (Page.IsPostBack)
    {
        Response.Write("Hello, world!  From AJAX.");
    }
    

    您不必使用 Page.IsPostBack,大多数 AJAX 请求只是 GET,所以如果您放入 Page_Load:

    Response.Write("Hello, world!  From AJAX.");
    

    然后对该页面执行 AJAX 调用,您将收到“Hello, world! From AJAX”。从 AJAX 调用返回。

    【讨论】:

    • 这很好用。非常感谢。我创建了一个单独的页面,它准确地返回了我正在寻找的内容。非常感谢。尽管从我从其他答案中读到的内容来看,这看起来是一种效率低下的方法。非常感谢!
    • 是的,理想情况下你会在 ASP 标记等中创建你的页面,这只是一个简单的例子。也正如其他人所说,ASP.NET AJAX 处理非常体面而且非常简单(您甚至不需要单独的页面或单独的代码) - 或者 jQuery 对于客户端同样出色,但正如您所说是一种学习练习。
    【解决方案2】:

    最好的办法是创建一个处理程序文件 (*.ashx) 来处理传入的请求并将正确格式化的 json/xml 返回到 JavaScript。 ScriptManager 用于提供这些内容直接嵌入到实际页面中,但是(除非您打算完全重建 ScriptManager)您会发现通过处理程序来完成它并绕过标准请求的 IIS 处理更简单。

    【讨论】:

    • 是的,你是对的。通用处理程序非常适合 ajax,因为它比 asp.net 页面轻量级。
    • 我一定会试试这个!非常感谢!
    【解决方案3】:

    ASP.Net 中的一个功能是能够从客户端代码调用服务器端代码而无需回发,使用称为客户端回调的东西。到目前为止,我发现了一些小警告:-

    • 它使用目前只有 IE 的 XmlHttp。 Firefox 和其他浏览器有替代方案,但回调仅使用此方案。
    • 您可以从服务器返回的唯一类型是字符串(但如果需要,我们可以通过序列化来解决这个问题)

    我使用的示例是我有两个需要保持同步的相关文本框。如果更改了 ClientID 框,则 ClientName 框应显示具有该 ID 的客户端的名称,反之亦然。

    要开始使用此功能,请确保您的代码隐藏实现 ICallbackEventHandler 接口:-

    public partial class WebForm1 : System.Web.UI.Page, ICallbackEventHandler
    

    接下来,我在我的 aspx.cs 中的 Page_Load 方法中注册我的回调方法:-

    // Set up client callbacks. These allow client-side scripts to call
    // server-side functions and retrieve the results. Its a string-only
    // return I'm afraid, limited by the ICallbackEventHandler method signatures
    
    txtClientID.Attributes.Add("onchange", "GetClientNameById('id|' + this.value, 'id');");
    
    string callBackClientID = Page.ClientScript.GetCallbackEventReference(this, "arg", "ClientNameCallback", "context", "ClientNameCallbackError", true);
    
    string clientIDfunction = "function GetClientNameById(arg,context) { " + callBackClientID + "; }";
    
    Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "GetClientNameById", clientIDfunction, true);
    
    txtClientName.Attributes.Add("onchange", "GetClientIdByName('name|' + this.value, 'name');");
    
    string callBackClientName = Page.ClientScript.GetCallbackEventReference(this, "arg", "ClientIdCallback", "context", "ClientIdCallbackError", true);
    
    string clientNamefunction = "function GetClientIdByName(arg, context) { " + callBackClientName + "; }";
    
    Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "GetClientIdByName", clientNamefunction, true);
    

    这会将服务器函数注册到页面并将它们连接到客户端回调方法 - 这些回调方法是基本的占位符,除了给服务器一个返回字符串的地方之外什么都不做。所以在 aspx 页面本身:-

    <script type="text/javascript">
    
    function ClientNameCallback(result, context)
    
    {
    
    //sorry about the hardcoded element name...
    
    if(result != "")
    
    document.getElementById('ctl00_ContentPlaceHolder1_txtClientName').setAttribute('value',result);
    
    }
    
    function ClientIdCallback(result,context)
    
    {
    
    //sorry about the hardcoded element name...
    
    if(result != "")
    
    document.getElementById('ctl00_ContentPlaceHolder1_txtClientID').setAttribute('value',result);
    
    }
    
    function ClientNameCallbackError(result, context)
    
    {
    
    //Not sure what error is likely to arise at this point, but...
    
    alert('Error in client name callback function - please say that to eSolutions!');
    
    }
    
    function ClientIdCallbackError(result, context)
    
    {
    
    //Not sure what error is likely to arise at this point, but...
    
    alert('Error in client id callback function - please say that to eSolutions!');
    
    }
    
    </script>
    

    最后,我们实现所需的 ICallbackEventHandler,其中包含我们要执行的服务器端处理:-

    string ICallbackEventHandler.GetCallbackResult()
    {
         return callbackReturnValue;
    }
    
    void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)
    {
    
    // eventArgument should be in format field|value,
    // e.g., "id|30102" or "name|test client" 
    // This is because of the "single string" limitations
    // of the callback interface
    
    if(eventArgument.StartsWith("name"))
    {
        //....do lookup to get the id based on the name, from an array or database, or whatever
        callbackReturnValue = <string we want to pass back to client-side
    }
    
    else if(eventArgument.StartsWith("id"))
    

    等等。 等等

    【讨论】:

    • 我得看看我是否比使用 Andy Shellam 描述的单独页面方式更喜欢这种方式
    【解决方案4】:

    this answer,+1 表示自己动手。

    但是,我必须强烈建议您在客户端使用像 jQuery 这样的库来解决浏览器之间的差异(在这种特定情况下,存在差异)。它(或其他库)将提供一种抽象,您可以在所有 Web 浏览器中使用它来规范您的代码。

    话虽如此,在 ASP.NET 中,您可以检查调用是否是回发,如果是,只需将内容写入输出流。

    然而,我强烈建议不要这样做。相反,对 ajax 的调用应该完全指向另一个页面,因为它提供了不同的目的、不同类型的响应,因此应该有自己的 URL。

    另外,请注意,当以 XML 或 JSON 形式返回内容时(这在 Ajax 调用中很常见,现在 JSON 占主导地位),将响应的 ContentType 属性更改为适当的 mime 类型很重要(“text/xml”用于 XML,“application/json”用于 JSON)。

    请注意,ASP.NET MVC 使这一切变得更加容易,您可能希望考虑使用它而不是 WebForms 模型,因为 MVC 是从头开始构建的,可以更轻松地处理其中许多场景。它允许您将处理页面呈现的方法与以 Ajax 调用形式提供功能的方法完全分开(这只是众多好处之一)。

    【讨论】:

    • 是的,在我完全了解如何手动完成并弄清楚所有内部工作原理之后,我很可能会转向 jQuery 之类的库。非常感谢。
    【解决方案5】:

    如果我的想法是正确的,您可以通过检查标头 X-Requested-With 来区分普通 HTTP 请求和 AJAX 调用。

    因此,在您的玩具示例中,如果您想对 AJAX 请求做出不同的响应:

    public void Page_Load(object sender, EventArgs e)
    {
        if (Request.Headers["X-Requested-With"] == "XMLHttpRequest")
        {
           Response.Clear(); // dont want <html>.... etc stuff
           Response.Write("Hi from AJAX!");
        }
        else
        {
            // normal page stuff
        }
    }
    

    然后,在你的 js 中,像这样(请原谅任何语法错误)

    var req = new XmlHttpRequest();
    req.open("GET","default.aspx",false);
    req.send("");
    document.getElementById('some_div').innerHTML = req.responseXML;
    

    【讨论】:

    • 嗯.. 不幸的是我无法让它工作。我需要做更多的调查,因为这似乎是一种有效的方法。非常感谢!
    • @Tomaszewski 哪个部分不起作用?如果您在 CS 代码中设置断点,是否触发了正确的代码块?
    • 您好,感谢您的回复。在调试时,我的 Request.Headers 似乎没有一个名为“X-Requested-With”的键,除非我遗漏了什么。
    • 虽然,我找到了这篇文章 (haacked.com/archive/2009/01/27/aspnetmvc-release-candidate.aspx),它似乎在谈论在 ASP.NET MVC 中这是有效的。我还没有尝试过 MVC。但是,它表明 WebForms 可能有一个自定义的“X-Requested-With”......或类似的东西。不确定我理解正确。
    猜你喜欢
    • 1970-01-01
    • 2011-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多