ModelState.IsValid или Model.IsValid? - PullRequest
       18

ModelState.IsValid или Model.IsValid?

10 голосов
/ 16 февраля 2011

Я пишу контроллер и модульные тесты для него, когда я натолкнулся на два способа (одинаково верных, я думаю) сделать что-то.Все мои модели имеют свойство IsValid, которое я могу проверить, чтобы спросить модель, является ли она действительной или нет.

При обратной передаче в метод действия контроллера, если модель верна, я хочу сохранить ее, в противном случае я хочу снова отобразить форму, чтобы пользователь мог исправить свои ошибки.

Первоначально я думал, что нужно просто проверить, запрашивается ли модель, является ли она действительной, но я понял, что могу также проверить ModelState.IsValid.

У кого-нибудь есть какая-то конкретная причина взглянуть на одно против другого?

Ответы [ 3 ]

12 голосов
/ 16 февраля 2011

Я думаю, что встроенная в вашу модель пользовательская проверка бизнеса - это хороший подход.Я бы обработал это, добавив любые пользовательские ошибки проверки в ModelState:

if (ModelState.IsValid)
{
    if (!model.IsValid)
    {
       ModelState.AddModelError("The model is not valid");
    }
    else
    {
        return RedirectToAction("Index");
    }
}

return View(model);

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

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

ModelState может быть переведено в TempData, чтобы следовать за Post-Redirect-Get. Пример:

    [HttpPost]
    [ExportModelStateToTempData]
    public ActionResult Delete(int id)
    {
        if (_service.DeleteTask(id))
            return RedirectToAction(ControllerActions.Index);

        return RedirectToAction(ControllerActions.Edit, new { id });
    }

    [ImportModelStateFromTempData]
    public ActionResult Edit(int id)
    {
        var task = _service.GetTask(id);
        return View(ControllerActions.Edit, GetEditModel(task));
    }

Пользователь может удалить задачу с помощью функции callig / Task / Delete, но если что-то пойдет не так и появится сообщение об ошибке, нажатие клавиши F5 не вызовет удаление снова. когда ModelState после перевода Delete в Edit, все ошибки отображаются на странице редактирования.

Это код для импорта / экспорта атрибутов ModelState:

public abstract class ModelStateTempDataTransferAttribute : ActionFilterAttribute
{
    protected static readonly string Key = typeof(ModelStateTempDataTransferAttribute).FullName;
}

public class ExportModelStateToTempDataAttribute : ModelStateTempDataTransferAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        //Only export when ModelState is not valid
        if (!filterContext.Controller.ViewData.ModelState.IsValid)
        {
            //Export if we are redirecting
            if ((filterContext.Result is RedirectResult) || (filterContext.Result is RedirectToRouteResult))
            {
                filterContext.Controller.TempData[Key] = filterContext.Controller.ViewData.ModelState;
            }
        }

        base.OnActionExecuted(filterContext);
    }
}

public class ImportModelStateFromTempDataAttribute : ModelStateTempDataTransferAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        ModelStateDictionary modelState = filterContext.Controller.TempData[Key] as ModelStateDictionary;

        if (modelState != null)
        {
            //Only Import if we are viewing
            if (filterContext.Result is ViewResult)
            {
                filterContext.Controller.ViewData.ModelState.Merge(modelState);
            }
            else
            {
                //Otherwise remove it.
                filterContext.Controller.TempData.Remove(Key);
            }
        }

        base.OnActionExecuted(filterContext);
    }
}

Делать то же самое с Model было бы очень проблематично.

0 голосов
/ 18 февраля 2016

Вы также можете перечислить через набор ошибок и записать точное сообщение об ошибке в вывод.

else if (!ModelState.IsValid)
{
    List<ModelError> modelErrors = new List<ModelError>();
    ModelErrorCollection errors = new ModelErrorCollection();
                              ;
    // got to the model and look at the Array of Values
    foreach (var item in ModelState)
    {
        if (item.Value.Errors.Count != 0)
        {
            // get the error
            errors = item.Value.Errors;
            modelErrors.Add(errors.Single());
        }
     }

     if (modelErrors.Count != 0)
     {
         foreach (var error in modelErrors)
         {
             Debug.WriteLine(error.ErrorMessage);
         }
      }

...

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