Правильный способ обработки вызовов Ajax в ASP.Net MVC 3 - PullRequest
14 голосов
/ 23 мая 2011

При кодировании вызовов Ajax в ASP.Net MVC у нас есть много вариантов, таких как отправка вызовов, обработка их на сервере и обработка успехов и неудач на клиенте.У некоторых вещей есть правильный ответ, но я не смог найти четкого руководства.Итак, сквозной, как правильно сделать вызов ajax?

Включая

  • Каков наилучший способ ввести URL-адрес действия для URLв вызов ajax?
  • Каковы соображения при выборе JsonBehavior?
  • Каков наилучший способ обработки ошибок на стороне сервера?
    • Должен ли обратный вызов error () на стороне клиента быть вызван какими-либо ошибками (например, неожиданным OutOfMemoryException) или только предвидимыми ошибками (например, неверный ввод)?
    • Каков наилучший способ экспорта ошибоктаким образом, что обратный вызов error () будет запущен.
    • Лучший способ гарантировать, что обратный вызов ошибки получает правильный код состояния и текст ответа.
    • Должны ли ошибки проверки приводить к ErrorCode Status или они должны быть частью отвечающего объекта проверки.
  • Каков наилучший способ обработки ошибок на стороне клиента?
    • Должны ли непредвиденные ошибки на стороне сервера отображаться так же, как сводка проверки?Может быть, просто «что-то пошло не так»?Должен ли клиент уметь различать эти два?

Есть ли у других какие-либо мнения, по которым у людей сильные мнения?

Ответы [ 3 ]

21 голосов
/ 24 мая 2011

Стиль вопросов / ответов

Каков наилучший способ ввести URL-адрес действия для URL-адреса в вызов Ajax?
Здесь нет соглашения, и это также во многом зависит от того, как ваш контент был доставлен клиенту. Было ли это с помощью представлений / частичных представлений (в этом случае вы могли генерировать URL-адреса с помощью вспомогательных методов Html / Url или это было чисто сгенерировано на клиенте (шаблонизатор и т. Д.). Довольно часто мы просто хотим использовать некоторые обычные элементы HTML расширить поведение Ajax (например, формы, кнопки и ссылки). В этой ситуации лучше предоставить правильные URL-адреса, которые мы также можем прочитать из них, и использовать их в наших сценариях (например, href в ссылках). пользователей, на которые указывают вещи. Будем ли мы преобразовывать их в запросы GET / POST / DELETE / PUT, больше не имеет значения. Я бы предложил избегать жесткого кодирования URL-адресов в ваших сценариях, поскольку вы можете изменить маршрутизацию или предоставить другие средства обработка. Использование помощников Html везде, где это возможно, намного лучший способ обслуживания. При добавлении URL-адресов к элементам, которые не поддерживают их автоматически (без атрибута href или src), вы всегда можете добавить их как пользовательские. атрибуты, особенно когда вы используете атрибут данных (например, data-href или аналогичный). Сообщение в блоге Джона Ресига об этом.

Каковы соображения при выборе JsonBehavior?
Лучше всего делать POST-запросы, когда нужно вернуть Json. В GET-запросах вы должны знать о возможных последствиях JSON Hijacking , это также причина, почему вы должны явно указать, что вы разрешаете получать запросы с результатами JSON.

Как лучше всего обрабатывать ошибки на стороне сервера?
Лучший способ обработки ошибок сервера (которые не могут и не должны подавляться) - это на самом деле информировать пользователя об ошибке. Подробности этого обычно не важны, так как пользователи не разбираются в разработке, но говорить им, что что-то пошло не так, это нормально. Особенно, если вы можете предложить им какое-то решение. А с помощью вызова Ajax можно возвращать ошибки как ошибки, которые могут быть обработаны с помощью функций Javascript обработчика ошибок. Я написал сообщение в блоге , в котором подробно описан весь процесс , а также приведен код, показывающий, как правильно обрабатывать ошибки проверки. Лично я считаю, что возвращать ошибки как успех неправильно. следовательно, я не Но это аргументировано. Действия моего контроллера довольно упрощены благодаря коду, который я использую:

[HandleModelStateException]
public ActionResult AddUser(User user)
{
    if (!this.ModelState.IsValid)
    {
        throw new ModelStateException(this.ModelState);
    }
    // process valid data
}

Должен ли обратный вызов error () на стороне клиента вызываться какими-либо ошибками (т. Е. Непредвиденными OutOfMemoryException) или только предвидимыми ошибками (т. Е. Неверными данными)?
Как указывалось ранее, об ошибках следует сообщать пользователям, когда они получат неожиданные результаты от того, что они инициировали. Не подавляйте ошибки, о которых им следует сообщать. Но не вдавайтесь в подробности. Исключение из-за недостатка памяти слишком сложно объяснить обычным пользователям компьютера. Сообщите что-нибудь дружелюбное и короткое.

Каков наилучший способ экспорта ошибок для запуска обратного вызова error().
Посмотрите мое сообщение в блоге и проверьте код, чтобы увидеть, как создавать ошибки, которые обрабатываются функцией error()

Лучший способ обеспечить обратный вызов ошибки - получить правильный код состояния и текст ответа.
То же сообщение в блоге

Если ошибки проверки приводят к ошибке StatusCode или они должны быть частью отвечающего объекта проверки.
Ошибки валидации по сути являются предупреждениями и должны рассматриваться как таковые. Вот почему вы можете увидеть положительный шаблон проверки формы на некоторых сайтах, которые также сообщают о достоверности данных, а не просто информировать пользователей о том, что они совершили еще одну ошибку. Ошибки валидации обычно коренятся в недопустимом пользовательском интерфейсе и недостаточной информации.

Как лучше всего обрабатывать ошибки на стороне клиента?
Это во многом зависит от вашего приложения, но я предлагаю вам следовать проверенным шаблонам, потому что пользователи, скорее всего, узнают подробности и не будут их путать.Как вы думаете, почему OpenOffice использует практически такой же интерфейс, как Microsoft Office?Потому что пользователи знают, как это работает, поэтому, скорее всего, познакомятся с приложением быстро и безболезненно.Но если вы можете, не относитесь к пользователям как к глупым людям.Используйте положительную проверку.Некоторые ошибки также должны отображаться как ошибки.Ой.Btw.Я использую ненавязчивую информацию в своем приложении, где информация, такая как успешная работа, сообщается пользователям, но не мешает их работе.Через некоторое время он автоматически исчезает.Подобно тому, что делает GMail.Он просто сообщает вам, что письмо было отправлено, и эта информация не нуждается в подтверждении.
jQuery ajax() functin поддерживает функции успеха и ошибок, поэтому разумно использовать оба.Снова: возвращать ошибки как успех не правильно.Нам не понадобятся функции ошибок, чем вообще.Мой фильтр действий HandleModelState возвращает ошибки с конкретным кодом ошибки 400, который также можно использовать, и его результат.

$.ajax({
    url: $(this).attr("href"),
    data: someDataObj,
    type: "POST",
    success: function(data){
        // process data
    },
    error: function(xhr, status, err){
        if (xhr.status = 400) {
            // handle my error in xhr.resposeText
        }
        else {
            // handle other errors that are cause by unknown processing
        }
    }
});

Должны ли непредвиденные ошибки на стороне сервера отображаться так же, как и сводка проверки?Может быть, просто " что-то пошло не так " диалог?Должен ли клиент различать эти два?
Людям не нравятся большие красные предупреждения.Если что-то является предупреждением по своей природе, оно должно рассматриваться более дружелюбно, чем фактические ошибки, которые мешают вашему приложению работать должным образом.В частности, валидация должна быть очень дружелюбной.Ошибки должны подтверждаться пользователями, а предупреждения, возможно, не должны.Зависит от их натуры.Но если это так, то, вероятно, это ошибки.

Надеюсь, это кое-что прояснит для вас.

6 голосов
/ 23 мая 2011

Каков наилучший способ ввести URL-адрес действия для URL-адреса в вызов ajax?

Лично я использую атрибуты data- * HTML5 для элементов DOM, которые я AJAXify.Например:

<div id="foo" data-url="@Url.Action("foo")">Foo Bar</div>

, а затем:

$('#foo').click(function() {
    var url = $(this).data('url');
    // TODO: perform the AJAX call
});

Конечно, если элемент DOM представляет якорь или форму, я бы использовал собственное свойство (action или href).

Какие соображения при выборе JsonBehavior?

Никаких особых соображений.Помните, что GET-запрос может кэшироваться клиентскими браузерами, поэтому вам может потребоваться указать { cache: false } на клиенте.Да, и, конечно, AllowGet на сервере для Json.

Каков наилучший способ обработки ошибок на стороне сервера?

Лично я использую FluentValidation.NET для обработкиошибки проверки на моих моделях представления.Также могут быть ошибки, приходящие из уровня обслуживания .

Каков наилучший способ обработки ошибок на стороне клиента?

Еслисервер возвращает JSON У меня обычно есть структура, которая выглядит следующим образом:

{ error = 'some error message', result: null }

или:

{ error = null, result: { foo: 'bar' } }

в зависимости от того, была ли ошибка, и на клиенте:

success: function(data) {
    if (data.error != null && data.error != '') {
        // error
    } else {
        // use data.result
    }
}

Я использую обратный вызов error для всего, что является необработанными исключениями на сервере, и в этом случае просто показывают общее сообщение об ошибке.Глобальный обработчик ошибок может быть задан с помощью $.ajaxSetup.

. Чтобы упростить генерацию этих результатов JSON на сервере и СУХИЕ мои действия, я использую фильтры настраиваемых действий, которые проверяют, является ли запрос запросом AJAX, и еслиэто был AJAX-запрос на проверку того, были ли ошибки проверки добавлены в ModelState, и если они заменяют результат действия пользовательской ошибкой JsonResult, чтобы обработать случай ошибки.

0 голосов
/ 23 мая 2011

Вот как я работаю в некоторых недавних проектах:

1) Я вставляю URL ajax в представление с помощью вызова Url.Action.

2) Jqgrid использует GET для выборки данных сетки, поэтому в действиях контроллера заливки сетки мне нужно использовать переключатель JsonRequestBehavior.AllowGet при вызове метода Json.

3) Я недавно переключился на ненавязчивую проверку Microsoft на стороне клиента, которая имеет аккуратный метод ModelState.IsValid, который вы можете запускать на стороне сервера в своем действии контроллера, чтобы убедиться, что такая же точная проверка также выполняется на стороне сервера без кода дублирования. Для маскировки / снятия маски данных потребовалась некоторая работа по объединению его с jquery.maskedinput и так далее, вот статья о том, как заставить все это работать .

4) Относительно отображения ошибки на стороне клиента, это проблема дизайна, которую должны прояснить заинтересованные стороны. Лично мне не понравилась проверка рядом с текстовыми полями или сводка проверки вверху страницы. Я предпочитаю, чтобы ошибки выскакивали на вашем лице, поэтому я подправил файл Microsoft jquery.validate.unobtrusive.js, чтобы показать ошибку во всплывающем модальном диалоговом окне. Вы можете увидеть код в решении выше в файле jquery.validate.unobtrusive.MOD.js (обратите внимание, что моя версия имеет суффикс «.mod.js»), и вы можете увидеть диалог ошибки в Site.Master.

Пример действия контроллера:

[HttpPost]
    public ActionResult Index(PersonalInformation model)
    {
        if (ModelState.IsValid)
        {
            // TODO: sell personal information to sleazeballs

            TempData["PersonalInformation"] = model;

            return RedirectToAction("Success");
        }

        // If we got this far, something failed, redisplay form
        Index_Load();
        return View(model);
    }

Надеюсь, это поможет,

Роберт

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