如果ModelState.IsValid失败,请获取错误消息?

时间:2011-03-06 17:50:56

标签: c# asp.net asp.net-mvc

我的控制器中有这个功能。

[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不断返回false并重新显示视图。但我不知道错误是什么。

有没有办法获取错误并将其重新显示给用户?

13 个答案:

答案 0 :(得分:119)

试试这个

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

错误将是所有错误的列表。

如果要向用户显示错误,您只需将模型返回到视图,如果尚未删除Razor @Html.ValidationFor()表达式,则会显示错误。

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

该视图将显示每个字段旁边和/或ValidationSummary中的任何验证错误(如果存在)。

答案 1 :(得分:70)

如果您希望生成包含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);
}

答案 2 :(得分:32)

您可以在视图中执行此操作,而无需在操作中执行任何特殊操作,方法是使用Html.ValidationSummary()显示所有错误消息,或Html.ValidationMessageFor()显示模型特定属性的消息。

如果您仍需要查看操作或控制器中的错误,请参阅ModelState.Errors属性

答案 3 :(得分:5)

如果模态不是有效的&由于您的控件处于折叠式手风琴中,因此无法在屏幕上看到错误,然后您可以返回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);
}

但请注意,此代码将记录所有验证错误。因此,只有在出现无法在屏幕上看到错误的情况时才应使用此方法。

答案 4 :(得分:2)

这是一个有用的片段,我可以复制/粘贴到我的 OnPostASync() 处理程序中以快速识别失败的验证项目:

public async Task<IActionResult> OnPostAsync(string editButton)
    {
        if (!ModelState.IsValid)
        {
            var errors = 
                from value in ModelState.Values
                where value.ValidationState == ModelValidationState.Invalid
                select value;  
            return Page();  // <-- I set a breakpoint here, and examine "errors"
        }
        ...

与上面的其他一些解决方案不同,我可以看到两者

  1. 错误信息文本(ErrorMessage) ... 和 ...
  2. 导致错误的特定字段

答案 5 :(得分:0)

我不知道这是不是你的问题,但是如果你添加一个用户,然后更改你的应用程序的名称,那么该用户将保留在数据库中(当然),但是无效(这是正确的行为) 。但是,此类故障不会添加任何错误。错误列表为空,但ModelState.IsValid将为登录返回false。

答案 6 :(得分:0)

确定并加入观看:

  1. 在您的代码中的ModelState行执行断点
  2. 将您的模型状态添加到您的手表
  3. 展开ModelState“值”
  4. 展开值“结果视图”
  5. 现在,您可以在值的末尾看到所有SubKey及其验证状态的列表。

    因此,搜索无效值

答案 7 :(得分:0)

这是示例扩展名

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;
    }
}

答案 8 :(得分:0)

尝试

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

答案 9 :(得分:0)

如果有人在使用WebApi(不是MVC),则只需返回ModelState对象:

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

答案 10 :(得分:0)

ModelState.Values.SelectMany(v => v.Errors).ToList().ForEach(x => _logger.Error($"{x.ErrorMessage}\n"));

答案 11 :(得分:0)

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

OR

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);
            }
        }

答案 12 :(得分:0)

我将此方法用作获取错误的通用方法

 public static List<string> GetModelErrros(ModelStateDictionary modelState)
        {
            var errors = modelState.Values.Where(E => E.Errors.Count > 0)
                         .SelectMany(E => E.Errors)
                         .Select(E => E.ErrorMessage)
                         .ToList();

            return errors;
        }

你可以使用它

logger.LogInformation("ID {0} input Error  ", string.Join(",", SiteUtils.GetModelErrros(ModelState)));