Quantcast
Channel: ASPNETWebStack Issue Tracker Rss Feed
Viewing all articles
Browse latest Browse all 7215

Edited Issue: WebApi validation ignores ErrorMessage in Required Data Annotation attribute [1471]

$
0
0
WebApi validation ignores custom Error Message in Required Data Annotation attribute.

Given the code:

View Model:
```
public class InputVM : IValidatableObject
{
#region Properties

/// <summary>
/// Duration period
/// </summary>
[Required(ErrorMessage = "Custom duration required message")]
public int? Duration { get; set; }

(...)
}
```

Controller:
```
public class SampleApiController : ApiController
{
// GET /api/dummyoutput/
public HttpResponseMessage GetDummyOutput([FromUri]InputVM vm)
{

if(ModelState.IsValid == false)
{
return Request.CreateResponse(HttpStatusCode.BadRequest, ModelState);
}

var service = new DummyDataService();
var vm = service.GetDummyOutput(vm);
return Request.CreateResponse<CalculatorVM>(HttpStatusCode.OK, vm);
}
```

WebApi Config:
```
config.Services.RemoveAll(typeof(System.Web.Http.Validation.ModelValidatorProvider),
v => v is InvalidModelValidatorProvider);
config.Formatters.Remove(config.Formatters.XmlFormatter);

var json = config.Formatters.JsonFormatter;
json.UseDataContractJsonSerializer = false;
json.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
json.SerializerSettings.Formatting = Formatting.Indented;
json.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();

config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.LocalOnly;

config.Routes.MapHttpRoute(
name: "DummyoutputApi",
routeTemplate: "api/dummyoutput",
defaults: new { controller = "SampleApi", action = "GetDummyOutput" }
);
```

When i miss the Duration field in query string, it will give me back JSON / XML with:
"The Duration property is required." instead of my custom error.

It's really hard to live with it with a localization requirement. :)

Hint: it only concerns Required validator - as a workaround i have written RequiredLocalized validator which does the same job - and it works:

Workaround validator:
```
/// <summary>
/// Localized Required validation for Web Api.
/// By default, the returned Error Message is hardcoded (bug).
/// </summary>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = false)]
public class RequiredLocalizedValidator : ValidationAttribute, IClientValidatable
{
public override bool IsValid(object value)
{
return (value == null) == false;
}

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
yield return new ModelClientValidationRule()
{
ErrorMessage = ErrorMessage,
ValidationType = "requiredlocalized"
};
}
}
```
Usage on view model:
```
public class InputVM : IValidatableObject
{
#region Properties

/// <summary>
/// Duration period
/// </summary>
//[Required(ErrorMessage = "Custom duration required message")]
[RequiredLocalizedValidator(ErrorMessage = "Custom duration required message")]
public int? Duration { get; set; }

(...)
}
```

Best Regards,
Tom

Viewing all articles
Browse latest Browse all 7215

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>