C# 如果ModelState.IsValid失败,是否获取错误消息?

C# 如果ModelState.IsValid失败,是否获取错误消息?,c#,asp.net,asp.net-mvc,C#,Asp.net,Asp.net Mvc,我的控制器中有这个功能 [HttpPost] public ActionResult Edit(EmployeesViewModel viewModel) { Employee employee = GetEmployee(viewModel.EmployeeId); TryUpdateModel(employee); if (ModelState.IsValid) { SaveEmployee(employee); TempDa

我的控制器中有这个功能

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


是否有方法获取错误并将其重新显示给用户?

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


如果您仍然需要查看操作或控制器中的错误,请查看属性

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

尝试此操作

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(如果存在)中显示任何验证错误。

如果您希望生成一个包含
ModelState
错误消息的错误消息字符串,则可以使用该字符串将错误平铺到一个列表中:

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

如果模式状态无效&由于控件处于折叠状态,因此无法在屏幕上看到错误,则可以返回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);
}

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

确定检查并添加到监视:

  • 在代码的ModelState行中设置断点
  • 将模型状态添加到手表中
  • 展开ModelState“值”
  • 展开值“结果视图”
  • 现在您可以看到所有子键的列表,其验证状态位于值的末尾

    因此,搜索无效值。

    这是示例扩展

    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;
        }
    }
    
    公共类GetModelErrors
    {
    //使用返回Json以查看:
    //返回Json(new{state=false,message=new-GetModelErrors(ModelState).MessagesWithKeys()});
    公共类密钥消息
    {
    公共字符串密钥{get;set;}
    公共字符串消息{get;set;}
    }
    私有只读ModelStateDictionary\u条目;
    公共GetModelErrors(ModelStateDictionary条目)
    {
    _入口=入口;
    }
    公共整数计数()
    {
    return\u entry.ErrorCount;
    }
    公共字符串异常(字符串sp=“\n”)
    {
    返回string.Join(sp,_entry.Values
    .SelectMany(v=>v.Errors)
    .选择(e=>e.Exception));
    }
    公共字符串消息(字符串sp=“\n”)
    {
    string msg=string.Empty;
    foreach(风险值项目在_条目中)
    {
    if(item.Value.ValidationState==modelvidationState.Invalid)
    {
    msg+=string.Join(sp,string.Join(“,”,item.Value.Errors.Select(i=>i.ErrorMessage));
    }
    }
    返回味精;
    }
    公共列表消息swithkeys(string sp=“● ")
    {
    列表=新列表();
    foreach(风险值项目在_条目中)
    {
    if(item.Value.ValidationState==modelvidationState.Invalid)
    {
    列表。添加(新的关键消息)
    {
    Key=item.Key,
    Message=string.Join(null,item.Value.Errors.Select(i=>sp+i.ErrorMessage))
    });
    }
    }
    退货清单;
    }
    }
    
    试试看


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

    返回请求.CreateErrorResponse(HttpStatusCode.BadRequest,ModelState);


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

    公共异步任务OnPostAsync(字符串编辑按钮) { 如果(!ModelState.IsValid) { 变量错误= 来自ModelState.Values中的值 其中value.ValidationState==modelvidationState.Invalid 选择值;
    返回页();//有时未提供
    错误消息
    ,例如,如果未设置必需的
    日期时间
    字段。在这种情况下,请查找异常消息,例如
    e.exception.message
    。有时也未提供该消息!我有一个
    模型状态
    ,其中有5个错误,每个错误都有一个空
    异常
    ,并且string表示
    ErrorMessage
    ,而
    ModelState
    上的其他条目则没有与其关联的
    Errors
    。没有ModelState.Errors属性?!@niico我想他指的是“ModelState”类型的属性,而Controller.ModelState属性的类型为ModelStateDictionary。@niico ModelState。错误只存在于MVC,而不是WebAPIT。在这之前,它已被解决。请尝试查看上面的@johnnyHK answer。是否可以获取名称/消息对,以便我们知道哪个字段有错误?
    ModelState.Values.First().Errors[0].ErrorMessage
    
    ModelState.Values.SelectMany(v => v.Errors).ToList().ForEach(x => _logger.Error($"{x.ErrorMessage}\n"));
    
    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);
                }
            }
    
    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"
            }
            ...