ASP.NET Платформа проверки MVC при публикации через jquery $.ajax?

StackOverflow https://stackoverflow.com/questions/1543465

Вопрос

Существует множество очень хороших сообщений и объяснений, как реализовать проверку с помощью ASP.NET MVC, и я предпочитаю одно из этих:

Тем не менее, мне действительно нравится вызывать ActionMethods с помощью метода jquery $.ajax.Одна из причин, по которой я хочу использовать $.ajax, заключается в том, что на страницу будет динамически загружаться множество частичных представлений (даже форма для создания сущности) с помощью вызовов $.ajax, и я не могу просто вернуть представление - я потеряю все динамически загружаемое содержимое.

Чтобы дать вам лучшее представление о проблеме, я опубликую несколько простых кодов, объясняющих, как я хотел бы вызывать действия контроллеров и обрабатывать ответы в клиентском коде jquery.

Метод действия контроллеров:

    public ActionResult CreateCustomer(string name, string accountNumber)
    {
        try
        {
            CustomerService.InsertCustomer(name, accountNumber);

            return Json(new ActionInfo()
            {
                Success = true,
                Message = "Customer Is Successfully Created"
            });

        }
        catch (Exception ex)
        {
            return Json(new ActionInfo()
            {
                Success = false,
                Message = ex.Message
            });
        }
    }

Вызов и обработка в клиентском коде:

$.ajax({
type: "POST",
url: $form.attr('action'),// /MyController/CreateCustomer
data: $form.serialize(),
error: HandleUnespectedError,
dataType: "json",
success: function(response) {

    if (response.Success)
        alert("Success: " + response.Message);
    else
        alert("Error: " + response.Message);
}});

Есть ли хороший способ заставить некоторые из этих фреймворков проверки работать так, как мне нужно? Я знаю, что могу добавить ошибки проверки в ActionInfo, а затем обработать это в клиенте, но, я полагаю, это уже было бы построением моей единственной проверки.

Это было полезно?

Решение

Я добился большого успеха, выполняя проверку с помощью AJAX, используя атрибуты аннотаций данных.Для того чтобы проверить достоверность ваших данных, вы захотите использовать ModelState свойство, которое имеет собственное свойство, называемое IsValid.Я настоятельно рекомендую взглянуть на руководство по проверке атрибутов аннотаций данных с официального сайта ASP.NET MVC.

Во-первых, вы захотите изменить действие вашего контроллера, чтобы он принимал объект вашей модели в качестве параметра, а не отдельного имени и номера учетной записи.Это значительно упростит выполнение проверки, которую я продемонстрирую ниже.Исходя из вашего примера, я лучше всего предполагаю, что объект вашей модели называется или будет называться Customer .Возможно, у вас есть следующий код для определения объекта модели и действия вашего контроллера...

// model object
public class Customer
{
  public Int32 Id {get; set;}
  public String Name {get; set;}
  public String AccountNumber {get; set;}
}

// controller
public class CustomerController : Controller
{
  public ActionResult CreateCustomer( [Bind(Exclude = "Id")] Customer customer )
  {
     // controller action code
  }
}


Убедитесь, что имена полей вашей формы соответствуют именам свойств объекта Customer, чтобы ASP.NET MVC мог автоматически привязывать их.Атрибут "Bind" в данном случае указывает ASP.NET MVC игнорировать свойство "Id" класса Customer при привязке полей формы к свойствам модели.Поскольку это новый клиент, у нас еще нет идентификатора, поэтому мы можем безопасно оставить идентификатор таким, каким бы ни было значение по умолчанию, и предоставить уровню данных самим решать, как лучше его сгенерировать.

Как только контроллер сконструирует объект модели для метода действия, его достоверность можно легко проверить с помощью ModelState.IsValid собственность.Как и следовало ожидать, он вернет true, если свойства модели допустимы, или false, если 1 или более свойств недопустимы.

Из первоначального вопроса следует, что CustomerService.InsertCustomer метод выбрасывает исключения при сбое проверки.В этом совершенно нет необходимости.InsertCustomer должен выполнять только те операции с данными, которые необходимы для вставки новой записи.Если вы не хотите абстрагировать исключения, специфичные для конкретной реализации, такие как SQLException, InsertCustomer на самом деле не должен перехватывать или генерировать какие-либо исключения, но, скорее всего, может просто разрешить любым исключениям всплывать на контроллер (или кем бы ни был вызывающий).

Конечным результатом всего этого может быть действие контроллера, которое выглядит следующим образом:

public ActionResult CreateCustomer( [Bind(Exclude = "Id")] Customer customer )
{
  // model is invalid
  if (!ModelState.IsValid)
  {
    return Json(new ActionInfo()
    {
      Success = false,
      Message = "Validation failed" // you will probably want a more robust message :-)
    });
  }

  // service method accepts a Customer object rather than arbitrary strings  
  CustomerService.InsertCustomer(customer);

  return Json(new ActionInfo()
  {
    Success = true,
    Message = "Customer created successfully."
  });

}


Если вы хотите сообщать о неожиданных ошибках, таких как исключения, связанные с базой данных, то вы, безусловно, можете добавить блок try / catch вокруг вызова InsertCustomer и вернуть необходимый результат для отображения сообщения об ошибке обратно клиенту.

Другие советы

Прошло больше года после того, как вы задали свой вопрос, но я рассмотрел проверку на стороне сервера с помощью вызовов Ajax в моем запись в блоге это может представлять для вас большой интерес.Я вижу, что вы возвращаете неудачные результаты как успешные HTTP-вызовы.Я справился с этим по-другому (я думаю, это более правильно, поскольку $.ajax обладает способностью success и error функциональность ответа).И ваш конкретный пример - идеальный пример, который может быть реализован с помощью функциональности, которую я объясняю в своем посте в блоге.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top