Я предпочитаю использовать jQuery с моими приложениями ASP.NET MVC, чем библиотеку Microsoft Ajax. Я добавляю к своим действиям параметр под названием «режим», который я установил в своих вызовах ajax. Если он указан, я возвращаю JsonViewResult. Если он не предоставлен, я предполагаю, что это был стандартный пост Http, и возвращаю ViewResult.
Я хотел бы иметь возможность использовать что-то похожее на IsMvcAjaxRequest в моих контроллерах при использовании jQuery, чтобы я мог исключить дополнительный параметр в своих действиях.
Есть ли что-нибудь, что могло бы предоставить эту возможность в моих контроллерах или какой-то простой способ ее реализовать? Я не хочу сходить с ума при написании кода, поскольку добавление одного параметра работает, это просто не идеально.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


См. Ответ Саймонса ниже. Описываемый здесь метод больше не нужен в последней версии ASP.NET MVC.
В настоящее время метод расширения IsMvcAjaxRequest работает так, что он проверяет Request["__MVCASYNCPOST"] == "true" и работает только тогда, когда метод является запросом HTTP POST.
Если вы выполняете HTTP-запросы POST через jQuery, вы можете динамически вставлять значение __MVCASYNCPOST в свой запрос, а затем вы можете воспользоваться методом расширения IsMvcAjaxRequest.
Вот ссылка на источник метода расширения IsMvcAjaxRequest для вашего удобства.
В качестве альтернативы вы можете создать клон метода расширения IsMvcAjaxRequest под названием
IsjQueryAjaxRequest, который проверяет Request["__JQUERYASYNCPOST"] == "true", и вы можете динамически вставлять это значение в HTTP POST.
Обновлять
Я решил пойти дальше и попробовать, вот что я придумал.
Метод расширения
public static class HttpRequestBaseExtensions
{
public static bool IsjQueryAjaxRequest(this HttpRequestBase request)
{
if (request == null)
throw new ArgumentNullException("request");
return request["__JQUERYASYNCPOST"] == "true";
}
}
Проверка из действия, является ли метод запросом jQuery $ .ajax ():
if (Request.IsjQueryAjaxRequest())
//some code here
JavaScript
$('form input[type=submit]').click(function(evt) {
//intercept submit button and use AJAX instead
evt.preventDefault();
$.ajax(
{
type: "POST",
url: "<%= Url.Action("Create") %>",
dataType: "json",
data: { "__JQUERYASYNCPOST": "true" },
success: function(data) {alert(':)');},
error: function(res, textStatus, errorThrown) {alert(':(');}
}
);
});
Могу ли я передать __JQUERYASYNCPOST так же, как любой другой параметр в моих данных сообщения при использовании «$ .post»? Если это так, это дало бы мне такую же базовую настройку без дополнительного параметра, что было бы идеально.
Да, передать значения в параметре данных $ .post (). Я бы сначала протестировал с __MVCASYNCPOST, чтобы убедиться, что он работает с существующими методами расширения. Если это так, вы можете реализовать свой собственный метод расширения и изменить его на __JQUERYASYNCPOST.
Еще раз спасибо, я только что реализовал код в проекте, над которым работаю. Если бы я посмотрел сюда еще раз перед тем, как писать, я бы просто сделал копипаст :)
Пожалуйста, смотрите мой ответ ниже, чтобы узнать о важных изменениях в RC1
Хорошо, я сделал еще один шаг вперед и изменил свой файл jQuery, чтобы загрузить дополнительный параметр в данные публикации, поэтому мне не нужно повторять «__JQUERYASYNCPOST: true» для каждого вызова для публикации. Для всех, кто заинтересован, вот как выглядит мое новое определение для $ .post:
post: function(url, data, callback, type) {
var postIdentifier = {};
if (jQuery.isFunction(data)) {
callback = data;
data = {};
}
else {
postIdentifier = { __JQUERYASYNCPOST: true };
jQuery.extend(data, postIdentifier);
}
return jQuery.ajax({
type: "POST",
url: url,
data: data,
success: callback,
dataType: type
});
}
Я добавил переменную postIdentifier, а также вызов jQuery.extend. Теперь помощник, описанный в ответе ложки16, работает без необходимости добавлять что-либо особенное в мой код jQuery на уровне страницы.
хорошо ... это один из самых полных QA на SO :)
Что, если бы вы расширили ajax ()? Разве это не было бы лучше, если бы все другие методы, такие как post (), просто вызывали ajax?
Я мог бы расширить ajax, но меня больше всего беспокоит публикация сообщений. Обычно я использую get для Ajax только в том случае, если это функция только для ajax, такая как поиск автозаполнения или аналогичные функции, которые были бы недоступны без ajax, поэтому для этих вещей я все равно использую JsonResult.
Почему бы вам просто не проверить HTTP-заголовок «X-Requested-With», который автоматически отправляется большинством библиотек Javascript (например, jQuery)?
Он имеет значение XMLHttpRequest, когда отправляется запрос GET или POST.
Чтобы проверить это, вам просто нужно проверить коллекцию NameValueCollection "Request.Headers" в вашем действии, то есть:
if (Request.Headers["X-Requested-With"] == "XMLHttpRequest")
return Json(...);
else
return View();
Таким образом, вы можете просто отличить обычные запросы браузера от запросов Ajax.
Отличная идея. Я воздержусь от изменения своего ответа, чтобы вы получили как можно больше репутации :)
Я не знал, что там вообще был запрошенный заголовок. Я проверю это и попробую, возможно, я обновлю метод расширения, чтобы проверить это. Есть идеи, почему MSFT не сделала бы этого с самого начала?
На самом деле, насколько мне известно, по этой теме нет стандартизации. Все библиотеки создают свои заголовки по-разному (некоторые указывают версию библиотеки), но, к счастью, большинство из них приняли «X-Requested-With», я не могу сказать, почему Microsoft этого не сделала.
@sork хорошо, что они узнают это теперь с RC1
Вот исключение из примечаний к выпуску MVC RC1 - январь 2009 г.
IsMvcAjaxRequest переименован в IsAjaxRequest
The IsMvcAjaxRequest method been renamed to IsAjaxRequest. As part of this change, the IsAjaxRequest method was updated to recognize the X-Requested-With HTTP header. This is a well known header sent by the major JavaScript libraries such as Prototype.js, jQuery, and Dojo.
The ASP.NET AJAX helpers were updated to send this header in requests. However, they continue to also send it in the body of the form post in order to work around the issue of firewalls that strip unknown headers.
Другими словами, он был специально переименован, чтобы быть более «совместимым» с другими библиотеками.
Кроме того, всем, кто не читал полные примечания к выпуску, но использовал предыдущие версии - даже такие недавние, как бета-версия - я СИЛЬНО рекомендую прочитать их полностью. Это сэкономит вам время в будущем и, скорее всего, заинтересует вас некоторыми новыми функциями. Удивительно, сколько там нового.
Важная заметка: Вам нужно будет убедиться, что вы обновили файл .js для MicrosoftAjax.MVC (не точное имя) при обновлении до RC1 из бета-версии - иначе этот метод не сработает. Это не указано в примечаниях к выпуску как обязательная задача для обновления, так что не забудьте.
Спасибо, Саймон, надеюсь, Эндрю Ван Слаарс даст вам принятый ответ.
Кроме того, я изменил свое сообщение на вики сообщества на случай, если другие захотят обновить «Принятый ответ».
благодаря. я уверен, что мой ответ тоже когда-нибудь устареет :) Я даже не слышал об ASP.NET MVC, когда вы писали свой ответ :)
для всех, кто запутался, IsMvcAjaxRequest теперь переименован (начиная с RC1) только в IsAjaxRequest специально для того, чтобы сделать его совместимым с другими библиотеками Ajax. пожалуйста, посмотрите мой пост ниже