Выполнение AJAX-вызовов вручную в ASP.NET и C # - PullRequest
9 голосов
/ 16 февраля 2010

Я хочу написать свой собственный AJAX в ASP.NET, а не использовать ASP.NET ScriptManager и т. Д.

ПОЧЕМУ? Мне нравится делать вещи вручную и знать, как все работает изнутри, поэтому я просто хочу сделать это для себя.

Итак, мой вопрос после того, как я сделаю AJAX-вызов:

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

Как я могу в C # добавить Page_Load (или нет), чтобы он прослушивал это и возвращал, например, строку.

Ответы [ 5 ]

6 голосов
/ 16 февраля 2010

Как и этот ответ , +1 за то, что вы делаете это сами.

Однако я должен настоятельно посоветовать вам использовать такую ​​библиотеку, как jQuery на стороне клиента для учета различий между браузерами (и в этом конкретном случае есть различия) , Он (или другие библиотеки) предоставит абстракцию, которую вы можете использовать во всех веб-браузерах для нормализации вашего кода.

При этом в ASP.NET вы можете проверить, является ли вызов возвращением, и если это так, просто записать содержимое в выходной поток.

Однако , я настоятельно рекомендую против этого. Скорее, вызов ajax должен полностью относиться к другой странице, так как он предоставляет другое назначение, другой тип ответа и, следовательно, заслуживает своего собственного URL.

Кроме того, обратите внимание, что при возврате содержимого в форме XML или JSON (что типично для вызовов Ajax, при этом JSON сейчас довольно доминирует) важно изменить свойство ContentType ответа на соответствующий тип MIME. («text / xml» для XML, «application / json» для JSON).

Обратите внимание, что ASP.NET MVC делает все это намного проще, и вы, возможно, захотите использовать его вместо модели WebForms, поскольку MVC построен с нуля, чтобы обрабатывать многие из этих сценариев гораздо проще. Он позволяет вам четко отделить методы, обрабатывающие рендеринг страницы, от методов, которые предоставляют функциональность в форме вызовов Ajax (и это только одно из многих преимуществ).

4 голосов
/ 16 февраля 2010

+ 1 для того, чтобы вы сами что-то делали - мне нравится знать, что я могу делать что-то сам, прежде чем использовать фреймворки, которые делают это для меня, поэтому, если все пойдет не так, я примерно знаю, как начать это исправлять.

В любом случае, до вашего вопроса. Просто выводите данные, как правило, используя ASP.NET или Response.Write. Если вы делаете запрос POST, вы можете проверить это в Page_Load, используя if (Page.IsPostBack.) Помните, что обычно вы будете отправлять данные только для части страницы, а не для всей страницы, поэтому вы вам не понадобятся теги <html>, <head> или <body>.

Когда я уже видел это на веб-сайтах ASP.NET, для вызовов AJAX использовались отдельные страницы (например, index.aspx = обычный сайт, index-ajax.aspx = ajaxified page page).

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

Вам не нужно использовать Page.IsPostBack, большинство запросов AJAX являются просто GET, поэтому, если вы введете в свой Page_Load:

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

Затем выполните вызов AJAX для этой страницы, и вы получите «Привет, мир! От AJAX». вернулся с вызова AJAX.

1 голос
/ 16 февраля 2010

Если я не ошибаюсь, вы можете отличить обычный 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;
1 голос
/ 16 февраля 2010

Лучше всего было бы создать файл обработчика (* .ashx), который будет обрабатывать входящий запрос и возвращать правильно отформатированный json / xml в JavaScript. ScriptManager используется для предоставления этого материала, встроенного непосредственно в фактическую страницу, но (если вы не собираетесь полностью перестраивать ScriptManager), вам будет проще сделать это через обработчик и обойти обработку IIS стандартного запроса.

0 голосов
/ 16 февраля 2010

Одной из функций ASP.Net является возможность вызова кода на стороне сервера из кода на стороне клиента без обратной передачи, используя так называемый обратный вызов клиента.Однако я обнаружил несколько незначительных предостережений: -

  • , он использует XmlHttp, который является IE только на данный момент.У Firefox и других браузеров есть альтернатива, но обратные вызовы используют только это.
  • единственный тип, который вы можете вернуть с сервера - это строка (но мы можем обойти это, сериализовав при необходимости)

В примере, который я использовал, у меня есть два связанных текстовых поля, которые нужно синхронизировать.Если поле ClientID изменено, в поле ClientName должно отображаться имя клиента с таким идентификатором, и наоборот.

Чтобы начать использовать эту функцию, убедитесь, что ваш программный код реализует интерфейс ICallbackEventHandler: -

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

Далее я регистрирую свои методы обратного вызова в методе Page_Load в моем aspx.cs: -

// 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"))

и т. Д.и т.д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...