Отримати повідомлення про помилку, якщо ModelState.IsValid не вдається?


80

У мене є ця функція в моєму контролері.

[HttpPost]
public ActionResult Edit(EmployeesViewModel viewModel)
{
    Employee employee = GetEmployee(viewModel.EmployeeId);
    TryUpdateModel(employee);

    if (ModelState.IsValid)
    {
        SaveEmployee(employee);
        TempData["message"] = "Employee has been saved.";
        return RedirectToAction("Details", new { id = employee.EmployeeID });
    }

    return View(viewModel); // validation error, so redisplay same view
}

Він постійно не вдається, ModelState.IsValidпостійно повертає помилковий і повторно відображає вигляд. Але я не уявляю, в чому помилка.

Чи є спосіб отримати помилку та повторно показати її користувачеві?


вона була вирішена до stackoverflow.com/questions/1352948 / ...
Hamzeh.Ebrahimi

Відповіді:


36

Ви можете зробити це у своєму поданні, не роблячи нічого особливого у своїй дії, використовуючи Html.ValidationSummary (), щоб показати всі повідомлення про помилки, або Html.ValidationMessageFor (), щоб показати повідомлення для певної властивості моделі.

Якщо вам все ще потрібно , щоб побачити помилки з вашого дії або контролера, см ModelState.Errors властивості


12
Немає властивості ModelState.Errors ?!
niico

@niico Я думаю, що він має на увазі властивість типу `ModelState", тоді як властивість Controller.ModelState має тип ModelStateDictionary.
devlord 02.03.18

3
@niico ModelState. Помилки існують лише для MVC, а не WebAPI
stuzor

146

Спробуйте це

if (ModelState.IsValid)
{
    //go on as normal
}
else
{
    var errors = ModelState.Select(x => x.Value.Errors)
                           .Where(y=>y.Count>0)
                           .ToList();
}

error - це список усіх помилок.

Якщо ви хочете показати помилки користувачеві, все, що вам потрібно зробити, це повернути модель у подання, і якщо ви не видалили @Html.ValidationFor()вирази Razor , вона з’явиться.

if (ModelState.IsValid)
{
    //go on as normal
}
else
{
    return View(model);
}

Представлення покаже будь-які помилки перевірки поруч із кожним полем та / або у ValidationSummary, якщо воно присутнє.


86

Якщо ви хочете створити єдиний рядок повідомлення про помилку, який містить ModelStateповідомлення про помилки, ви можете використати SelectManyдля згладження помилок в єдиний список:

if (!ModelState.IsValid)
{
    var message = string.Join(" | ", ModelState.Values
        .SelectMany(v => v.Errors)
        .Select(e => e.ErrorMessage));
    return new HttpStatusCodeResult(HttpStatusCode.BadRequest, message);
}

9
Іноді значення ErrorMessageне надається, наприклад, якщо DateTimeне встановлено обов’язкове поле. У цьому випадку шукайте повідомлення про виняток, наприклад e.Exception.Message.
WhatIsHeDoing

Іноді це теж не передбачено! У мене є ModelState5 помилок, кожна з яких містить нульовий Exceptionі порожній рядок, ErrorMessageтоді як інші записи ModelStateпросто не Errorsпов'язані з ними.
Метт Арнольд

6

Якщо стан модального значення не дійсний, і помилку неможливо побачити на екрані, оскільки ваш елемент керування знаходиться в згорнутому акордеоні, тоді ви можете повернути HttpStatusCode, щоб фактичне повідомлення про помилку відображалося, якщо ви робите F12. Також ви можете зареєструвати цю помилку в журналі помилок ELMAH. Нижче наведено код

if (!ModelState.IsValid)
{
              var message = string.Join(" | ", ModelState.Values
                                            .SelectMany(v => v.Errors)
                                            .Select(e => e.ErrorMessage));

                //Log This exception to ELMAH:
                Exception exception = new Exception(message.ToString());
                Elmah.ErrorSignal.FromCurrentContext().Raise(exception);

                //Return Status Code:
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest, message);
}

Але зауважте, що цей код реєструє всі помилки перевірки. Отже, це слід використовувати лише тоді, коли виникає така ситуація, коли ви не можете побачити помилки на екрані.


Чи можна було б отримати пари ім'я / повідомлення, щоб ми знали, в якому полі була помилка?
Matt

4

Якщо хтось тут для WebApi (не MVC), ви просто повертаєте ModelStateоб’єкт:

return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);


2

Добре перевірити та додати до перегляду:

  1. Зробіть точку зупинки в рядку ModelState у коді
  2. Додайте стан своєї моделі на годинник
  3. Розгорніть ModelState "Значення"
  4. Розгорніть значення "Перегляд результатів"

Тепер ви можете побачити список усіх SubKey з його станом перевірки в кінці значення.

Тож шукайте Недійсне значення .



1

Це розширення зразка

public class GetModelErrors
{
    //Usage return Json to View :
    //return Json(new { state = false, message = new GetModelErrors(ModelState).MessagesWithKeys() });
    public class KeyMessages
    {
        public string Key { get; set; }
        public string Message { get; set; }
    }
    private readonly ModelStateDictionary _entry;
    public GetModelErrors(ModelStateDictionary entry)
    {
        _entry = entry;
    }

    public int Count()
    {
        return _entry.ErrorCount;
    }
    public string Exceptions(string sp = "\n")
    {
        return string.Join(sp, _entry.Values
            .SelectMany(v => v.Errors)
            .Select(e => e.Exception));
    }
    public string Messages(string sp = "\n")
    {
        string msg = string.Empty;
        foreach (var item in _entry)
        {
            if (item.Value.ValidationState == ModelValidationState.Invalid)
            {
                msg += string.Join(sp, string.Join(",", item.Value.Errors.Select(i => i.ErrorMessage)));
            }
        }
        return msg;
    }

    public List<KeyMessages> MessagesWithKeys(string sp = "<p> ● ")
    {
        List<KeyMessages> list = new List<KeyMessages>();
        foreach (var item in _entry)
        {
            if (item.Value.ValidationState == ModelValidationState.Invalid)
            {
                list.Add(new KeyMessages
                {
                    Key = item.Key,
                    Message = string.Join(null, item.Value.Errors.Select(i => sp + i.ErrorMessage))
                });
            }
        }
        return list;
    }
}

0

Я не уявляю, чи це ваша проблема, але якщо ви додасте користувача, а потім зміните ім’я своєї програми, цей користувач залишиться в базі даних (звичайно), але буде недійсним (що є правильною поведінкою). Однак помилок для цього типу відмов не буде додано. Список помилок порожній, але ModelState.IsValid поверне false для входу.


0

Спробуйте

ModelState.Values.First().Errors[0].ErrorMessage

Це отримує лише перші помилки перших полів. спробуйте подивитися на відповідь @johnnyHK вище.
Janne Harju

0
publicIHttpActionResultPost(Productproduct) {  
    if (ModelState.IsValid) {  
        //Dosomethingwiththeproduct(notshown).  
        returnOk();  
    } else {  
        returnBadRequest();  
    }  
}

АБО

public HttpResponseMessage Post(Product product)
        {
            if (ModelState.IsValid)
            {
                // Do something with the product (not shown).

                return new HttpResponseMessage(HttpStatusCode.OK);
            }
            else
            {
                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
            }
        }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.