Выполнение вызовов AJAX вручную ASP.NET и C#
Я хочу написать свой собственный AJAX в ASP.NET, и не использовать ASP.NET ScriptManager, etc.
Почему? мне нравится делать вещи вручную и знать, как вещи работают изнутри, поэтому я просто хочу сделать это для себя.
Итак, мой вопрос: после того, как я сделаю вызов AJAX:
var ajaxCall = new XMLHttpRequest();
....
ajaxCall.send(null)
Как я могу в C# добавить в Page_Load (или нет), чтобы он слушал это и возвращал строку, например.
5 ответов
+1 для вас делать вещи самостоятельно-я хотел бы знать, что я могу делать вещи сам, прежде чем использовать рамки, которые делают это для меня, так что если он идет сиськи вверх, я примерно знаю, как начать исправлять его.
в любом случае на ваш вопрос. Как раз выходные данные нормально используя ASP.NET или ответ.Писать. Если вы делаете запрос POST, вы можете проверить это в Page_Load, используя if (Page.IsPostBack.) Помните, что обычно вы отправляете данные только для части страницы, а не для всей страницы сам, так что вам не понадобится <html>
, <head>
или <body>
теги.
когда я видел, как это делается в ASP.NET веб-сайты раньше для вызовов AJAX использовались отдельные страницы (например, index.aspx = обычный сайт, индекс-ajax.aspx = ajaxified компонент страницы.)
if (Page.IsPostBack)
{
Response.Write("Hello, world! From AJAX.");
}
вы не должны использовать страницу.IsPostBack, большинство запросов AJAX - это просто GET, поэтому, если вы поместите Page_Load:
Response.Write("Hello, world! From AJAX.");
затем сделайте вызов AJAX для этой страницы, вы получите " Привет, мир! Из "Аякса"." вернулся из AJAX-вызов.
Как ответ, +1 для того, чтобы сделать это самостоятельно.
Я должен сильно советую вам использовать библиотеку, как jQuery на стороне клиента для учета различий между браузерами (и в этом конкретном случае существуют различия). Он (или другие библиотеки) предоставит абстракцию, которую вы можете использовать во всех веб-браузерах для нормализации вашего кода.Это, как говорится, в ASP.NET, вы можете проверить, является ли вызов пост обратно, и если это так, просто напишите содержимое в выходной поток.
, Я бы настоятельно рекомендуем против этого. Скорее всего, вызов ajax должен быть на другой странице полностью, так как он предоставляет другую цель, другой вид ответа и, следовательно, заслуживает собственного URL.
кроме того, имейте в виду, что при возврате контента в виде XML или JSON (что типично для вызовов Ajax, когда JSON сейчас довольно доминирует), это важно чтобы изменить свойство ContentType ответа на соответствующий тип mime ("text/xml "для XML," application/json " для JSON).
обратите внимание, что ASP.NET MVC делает все это намного проще, и вы можете захотеть использовать это вместо модели WebForms, поскольку MVC построен с нуля, чтобы обрабатывать многие из этих сценариев намного проще. Он позволяет четко отделять методы, которые обрабатывают рендеринг страницы, от тех, которые предоставляют функциональность в виде вызовов Ajax (и это только одно из многих преимуществ).
лучше всего было бы создать файл обработчика (*.ashx), который будет обрабатывать входящий запрос и возвращать правильно отформатированный json/xml в JavaScript. ScriptManager используется для предоставления этого материала, встроенного непосредственно в фактическую страницу, но (если вы не собираетесь полностью перестроить ScriptManager), вам будет проще сделать это через обработчик и обойти обработку IIS стандартного запроса.
Если я прав в своем мышлении, вы можете отличить обычный HTTP-запрос от вызова AJAX, изучив заголовок X-Requested-With
.
Итак, в вашем примере игрушки, если вы хотите ответить по-другому на запрос 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;
одна из особенностей в ASP.Net возможность вызова кода на стороне сервера из кода на стороне клиента без обратной передачи, используя то, что называется обратным вызовом клиента. Есть несколько небольших предостережений, которые я нашел до сих пор: -
- он использует XmlHttp, который является IE только на данный момент. Firefox и другие браузеры имеют альтернативу, но обратные вызовы используют только это.
- единственный тип, который вы можете вернуть с сервера, - это строка (но мы можем обойти это сериализация при необходимости)
в Примере, который я использовал, у меня есть два связанных текстовых поля, которые нужно синхронизировать. Если поле ClientID изменено, в поле ClientName должно отображаться имя клиента, имеющего этот идентификатор, и наоборот.
чтобы начать использовать эту функциональность, убедитесь, что ваш код реализует интерфейс ICallbackEventHandler: -
public partial class WebForm1 : System.Web.UI.Page, ICallbackEventHandler
затем я регистрирую свои методы обратного вызова в методе Page_Load в моем aspx.цезий :-
// 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"))
etc. так далее.