For example, there is a Web Api action method:
public HttpMessageResponse Post(UserDto userDto)
{
if (!this.ModelState.IsValid)
{
return this.Req
For the first part:
Also error messages returned to a client shouldn't contain those prefixes
I agree having the parameter name as a prefix on all model state errors isn't great behavior. Fortunately, the service that has this behavior is replaceable. You just need to have a custom IBodyModelValidator. Here's what it would look like (using the Decorator pattern to let the default service do most of the work):
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);
}
}
Then, wrap the default service with yours:
config.Services.Replace(typeof(IBodyModelValidator), new PrefixlessBodyModelValidator(config.Services.GetBodyModelValidator()));
For the second part:
elso replace "modelState" with "errors"
The reason it currently says "modelState" is your current code:
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
Is effectively doing the following:
HttpError error = new HttpError(ModelState, false);
return Request.CreateResponse(HttpStatusCode.BadRequest, error);
Since HttpError is being serialized, and it has a property named "ModelState", that's what you see in the response.
If you want a different property name, you can use a custom error class:
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; }
}
And then create your response with this error type instead of HttpError:
PrettyHttpError error = new PrettyHttpError(ModelState);
return Request.CreateResponse(HttpStatusCode.BadRequest, error);
The combination of PrettyHttpError and PrefixlessBodyModelValidator gives the output you requested.