AcceptAjaxAttribute
это, вероятно, то, что нужно здесь; Тем не менее, я хотел бы предложить другой способ мышления об этой проблеме.
Не все запросы Ajax одинаковы. Ajax-запрос может пытаться выполнить любое из следующих действий:
- Привязка данных JSON к расширенной сетке (например, jqGrid);
- Анализ / преобразование данных XML, таких как канал RSS;
- Загрузка частичного HTML в область страницы;
- Асинхронная загрузка скрипта (
google.load
может это сделать);
- Обработка одностороннего сообщения от клиента;
- И, вероятно, еще несколько, которые я забыл.
Когда вы «выбираете» определенное «альтернативное действие», основанное исключительно на методе IsAjaxRequest
, вы привязываете что-то очень общее - асинхронный запрос - к определенной функциональности на сервере. Это в конечном итоге сделает ваш дизайн более хрупким, а также сделает ваш контроллер более сложным для модульного тестирования (хотя есть способы сделать это, вы можете смоделировать контекст).
Хорошо спроектированное действие должно быть согласованным , должно заботиться только о , для чего запрос был, а не как запрос сделан. Можно было бы указать на другие атрибуты, такие как AuthorizeAttribute
, как на исключения, но я бы сделал различие для фильтров, которые большую часть времени описывают поведение, которое должно происходить либо «до», либо «после», когда действие происходит, а не «вместо» из ".
Если подойти к делу, то цель, изложенная в вопросе, является хорошей; Вы должны определенно иметь разные методы для того, что правильно описано как разные действия:
public ActionResult Details(int id)
{
return View("Details", GetDetails(id));
}
public ActionResult JsonDetails(int id)
{
return Json(GetDetails(id));
}
public ActionResult PartialDetails(int id)
{
return PartialView("DetailTable", GetDetails(id));
}
И так далее. Однако использование селектора действий Ajax для выбора между этими методами следует практике «постепенной деградации» , которая по существу была заменена (по крайней мере IMO) прогрессивным улучшением .
Вот почему, хотя я люблю ASP.NET MVC, я в основном избегаю AjaxHelper
, потому что я не нахожу, что он так хорошо выражает эту концепцию; он пытается скрыть от тебя слишком много. Вместо понятия «форма Ajax» или «действие Ajax», давайте покончим с различием и придерживаемся прямого HTML, а затем добавим функциональность Ajax отдельно, как только мы уверены, что клиент может справиться с этим. .
Вот пример в jQuery - хотя вы можете сделать это и в MS AJAX:
$(function() {
$("#showdetails").click(function() {
$("#details").load("PartialDetails", { id: <%= Record.ID %> });
return false;
}
});
Это все, что нужно для добавления Ajax на страницу MVC. Начните с простой старой HTML-ссылки и переопределите ее с помощью Ajax-вызова , который переходит к другому действию контроллера .
Теперь, если где-то на вашем сайте вы решили использовать сетку, но не хотите разбивать страницы с помощью частичного рендеринга, вы можете написать что-то вроде этого (скажем, у вас есть один мастер- страница сведений со списком «заказов» слева и таблицей сведений справа):
$(".detaillink").click(function() {
$('#detailGrid').setGridParam({
url: $(this).attr("href").replace(/\/order\/details/i,
"/order/jsondetails")
});
$("#detailGrid").trigger("reloadGrid");
});
Этот подход полностью отделяет поведение клиента от поведения сервера. Сервер фактически говорит клиенту: Если вы хотите версию JSON, попросите версию JSON, и, кстати, вот скрипт для преобразования ваших ссылок, если вы знаете, как запустите его. Никаких селекторов действий и ошибок с перегрузками методов, никаких специальных насмешек, которые вы должны выполнить для запуска простого теста, нет путаницы в отношении того, какое действие делает, и когда. Всего пара строк JavaScript. Действия контроллера короткие и приятные, именно такими, какими они должны быть.
Это не единственный подход. Очевидно, что такие классы, как AcceptAjaxAttribute
, существуют, потому что они ожидали, что некоторые разработчики будут использовать метод обнаружения запросов. Но после долгих экспериментов с обоими я считаю, что намного легче рассуждать и, следовательно, легче правильно проектировать / кодировать.