在 ASP.NET 和 C# 中手动进行 AJAX 调用

Posted

技术标签:

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

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

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

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

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

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

【问题讨论】:

【参考方案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”......或类似的东西。不确定我理解正确。

以上是关于在 ASP.NET 和 C# 中手动进行 AJAX 调用的主要内容,如果未能解决你的问题,请参考以下文章

使用 jQuery 在 ASP.NET 中进行 AJAX 回调

C#实现简易ajax调用后台方法

ASP.NET C# SuppressFormsAuthenticationRedirect 不适用于 Ajax POST?

我需要使用 C# 和 ASP.Net 构建一个非常轻量级的 Ajax 引擎。你有啥建议?

ASP.NET / JavaScript - Ajax 调用,如何?

在 ASP.NET MVC 中使用 AJAX 方法时使用 C# 控制器重定向到页面