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

Commented 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
Comments: We are going to take a look, this seems to be broken only when using modelbinding (from URL). But either way using ErrorMessage= is not supporting Localization. You should use ErrorMessageResourceName instead. (of course after we make it work for URL, or in your custom property).

Viewing all articles
Browse latest Browse all 7215

Trending Articles



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