对于第一部分:
返回给客户端的错误消息也不应该包含这些前缀
我同意将参数名称作为所有模型状态错误的前缀并不是很好的行为。幸运的是,具有这种行为的服务是可替换的。您只需要一个自定义的 IBodyModelValidator。下面是它的样子(使用装饰器模式让默认服务完成大部分工作):
public class PrefixlessBodyModelValidator : IBodyModelValidator
{
private readonly IBodyModelValidator _innerValidator;
public PrefixlessBodyModelValidator(IBodyModelValidator innerValidator)
{
if (innerValidator == null)
{
throw new ArgumentNullException("innerValidator");
}
_innerValidator = innerValidator;
}
public bool Validate(object model, Type type, ModelMetadataProvider metadataProvider, HttpActionContext actionContext, string keyPrefix)
{
// Remove the keyPrefix but otherwise let innerValidator do what it normally does.
return _innerValidator.Validate(model, type, metadataProvider, actionContext, String.Empty);
}
}
然后,用你的包装默认服务:
config.Services.Replace(typeof(IBodyModelValidator), new PrefixlessBodyModelValidator(config.Services.GetBodyModelValidator()));
对于第二部分:
还将“modelState”替换为“errors”
它当前显示“modelState”的原因是您当前的代码:
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
正在有效地执行以下操作:
HttpError error = new HttpError(ModelState, false);
return Request.CreateResponse(HttpStatusCode.BadRequest, error);
由于 HttpError 正在被序列化,并且它有一个名为“ModelState”的属性,这就是您在响应中看到的内容。
如果您想要不同的属性名称,可以使用自定义错误类:
public class PrettyHttpError
{
public PrettyHttpError(ModelStateDictionary modelState)
{
Message = "Your request is invalid.";
Errors = new Dictionary<string, IEnumerable<string>>();
foreach (var item in modelState)
{
var itemErrors = new List<string>();
foreach (var childItem in item.Value.Errors)
{
itemErrors.Add(childItem.ErrorMessage);
}
Errors.Add(item.Key, itemErrors);
}
}
public string Message { get; set; }
public IDictionary<string, IEnumerable<string>> Errors { get; set; }
}
然后使用此错误类型而不是 HttpError 创建您的响应:
PrettyHttpError error = new PrettyHttpError(ModelState);
return Request.CreateResponse(HttpStatusCode.BadRequest, error);
PrettyHttpError 和 PrefixlessBodyModelValidator 的组合提供了您请求的输出。