MVC WebAPI 数据注释错误消息空字符串

ves*_*ous 5 asp.net-mvc-4 asp.net-web-api owin

我已经实现了一个 OWIN 自托管 webapi,并且正在尝试使用数据注释和 ActionFilterAttribute 将格式化的错误返回给用户。我在数据注释上设置了自定义错误消息,但是当我尝试从 ModelState 检索消息时,它始终是一个空字符串(如下图所示)。

在此处输入图片说明

模型:

public class JobPointer
{
    [Required(ErrorMessage = "JobId Required")]
    public Guid JobId { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

筛选:

public class ModelValidationFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if (actionContext.ModelState.IsValid) return;
        string errors = actionContext.ModelState.SelectMany(state => state.Value.Errors).Aggregate("", (current, error) => current + (error.ErrorMessage + ". "));

        actionContext.Response = actionContext.Request.CreateErrorResponse(
            HttpStatusCode.BadRequest, errors);
    }

}
Run Code Online (Sandbox Code Playgroud)

端点:

[HttpPost]
public HttpResponseMessage DescribeJob(JobPointer jobId)
{

   Job job = _jobhelper.GetJob(jobId.JobId);
   return Request.CreateResponse(HttpStatusCode.OK, job);
}
Run Code Online (Sandbox Code Playgroud)

请求正文:

{

}
Run Code Online (Sandbox Code Playgroud)

回复:

Status Code: 400
{
  "Message": ". "
}
Run Code Online (Sandbox Code Playgroud)

如果我将 ModelValidationFilter 中的 error.Message 更改为 error.Exception.Message 我会返回默认验证错误:

Status Code: 400
{
  "Message": "Required property 'JobId' not found in JSON. Path '', line 3, position 2.. "
}
Run Code Online (Sandbox Code Playgroud)

小智 2

我知道这是一个老问题,但我刚刚遇到这个问题并自己找到了解决方案。

正如您毫无疑问发现的那样,由于 Guid 是不可为 null 的类型 [Required] 会产生不友好的错误消息(我假设是因为 JSON 解析器在实际获得模型验证之前会选择它)。

您可以通过使 Guid 可为空来解决这个问题......

public class JobPointer
{
    [Required(ErrorMessage = "JobId Required")]
    public Guid? JobId { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

...但是,这并不是在所有情况下都是可行的选择(如我的情况),因此我最终编写了自己的验证属性,该属性将根据其空声明检查属性...

public class IsNotEmptyAttribute : ValidationAttribute
{

    public override bool IsValid(object value)
    {

        if (value == null) return false;

        var valueType = value.GetType();
        var emptyField = valueType.GetField("Empty");

        if (emptyField == null) return true;

        var emptyValue = emptyField.GetValue(null);

        return !value.Equals(emptyValue);

    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以像...

public class IsNotEmptyAttribute : ValidationAttribute
{

    public override bool IsValid(object value)
    {

        if (value == null) return false;

        var valueType = value.GetType();
        var emptyField = valueType.GetField("Empty");

        if (emptyField == null) return true;

        var emptyValue = emptyField.GetValue(null);

        return !value.Equals(emptyValue);

    }
}
Run Code Online (Sandbox Code Playgroud)