我已经实现了一个OWIN自托管webapi,我正在尝试使用数据注释和ActionFilterAttribute将格式化错误返回给用户.我在数据注释上设置了自定义错误消息,但是当我尝试从ModelState检索消息时,它总是一个空字符串(如下图所示).
模型:
public class JobPointer
{
[Required(ErrorMessage = "JobId Required")]
public Guid JobId { get; set; }
}
过滤:
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);
}
}
终点:
[HttpPost]
public HttpResponseMessage DescribeJob(JobPointer jobId)
{
Job job = _jobhelper.GetJob(jobId.JobId);
return Request.CreateResponse(HttpStatusCode.OK, job);
}
请求机构:
{
}
响应:
Status Code: 400
{
"Message": ". "
}
如果我将ModelValidationFilter中的error.Message更改为error.Exception.Message我返回默认验证错误:
Status Code: 400
{
"Message": "Required property 'JobId' not found in JSON. Path '', line 3, position 2.. "
}
最佳答案 我知道这是一个老问题,但我遇到了这个问题,并自己找到了解决方案.
毫无疑问,因为Guid是一个不可为空的类型[必需]会产生一个不友好的错误消息(我假设因为JSON解析器在实际获得模型验证之前就选择了它).
你可以通过让Guid可以为空来解决这个问题……
public class JobPointer
{
[Required(ErrorMessage = "JobId Required")]
public Guid? JobId { get; set; }
}
…但是,这在所有情况下都不是一个可行的选择(就像我的情况一样),所以我最终编写了自己的验证属性,该属性将根据它的空声明检查属性…
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);
}
}
你可以实现像…
public class JobPointer
{
[IsNotEmpty(ErrorMessage = "JobId Required")]
public Guid JobId { get; set; }
}