Globally localize validation - validation

I'm using System.ComponeneModel.DataAnnotations attributes such as Required and StringLength. Is it possible to localize its error messages globally?
I know I can do this
[Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(Resources.Validation))]
But doing this everywhere I use required attribute would be just insane. Also I'd like to avoid stuff like:
public class LocalizedRequiredAttribute : RequiredAttribute {
public LocalizedRequiredAttribute()
: base() {
ErrorMessageResourceName = "Required";
ErrorMessageResourceType = typeof(Resources.Validation);
}
}
(but if there isn't any other way, I'll settle for this)

AFAIK you need either a custom attribute or specify the ErrorMessageResourceName and ErrorMessageResourceType properties. There is another possibility detailed here:
Create a global resource class in
App_GlobalResources, and set
DefaultModelBinder.ResourceClassKey to
the name of this class (for example,
if you made "Messages.resx", then set
ResourceClassKey to "Messages").
There are two strings you can override
in MVC 2:
The string value for
"PropertyValueInvalid" is used when
the data the user entered isn't
compatible with the data type (for
example, typing in "abc" for an
integer field). The default message
for this is: "The value '{0}' is not
valid for {1}."
The string value for
"PropertyValueRequired" is used when
the user did not enter any data for a
field which is not nullable (for
example, an integer field). The
default message for this is: "A value
is required."
It's important to note
in the second case that, if you have
the
DataAnnotationsModelValidatorProvider
in your validator providers list
(which it is by default), then you
will never see this second message.
This provider sees non-optional fields
and adds an implied [Required]
attribute to them so that their
messages will be consistent with other
fields with explicit [Required]
attributes and to ensure that you get
client-side validation for required
fields.

For MVC3 see DataAnnotationsResources. It's "RequiredAttribute_ValidationError" and more.
You may solve it by installing .NET Framework language pack(s).
See also

Related

Why model validation is not working

I have following Model class that is used during the Web API Post. As you can see Id field is annotated as Required.
public class Model
{
[Required]
public Guid Id { get; set; }
}
The Post for API is as follows
[HttpPost]
public IActionResult Post([FromBody]Model value)
{
if (!ModelState.IsValid)
return BadRequest();
Model newModel = new Model() { Id = value.Id };
return Ok(newModel);
}
On a sunny day, this is what I see. All good
enter image description here
On a rainy day, when Id is not provided, I get following.
enter image description here
Given that in the second example, a Required field is not provided, shouldn't a BadRequest is returned rather than a 200 with invalid id guid with 00000000-0000-0000-0000-000000000000?
Using the Required annotation
In the Web API Docs, your issue is known as 'under-posting'.
The issue is that Guid has a default value, so when no value is provided, it is initialized with the default value... which then satisfies the Required constraint.
To prevent this, counter-intuitively you make the Guid nullable using Guid?.
Then if the value is not provided, the deserializer will set the value to null, which will cause the Required constraint to be violated.
If the value is provided, it will be set, and all will be well.
See https://www.asp.net/web-api/overview/formats-and-model-binding/model-validation-in-aspnet-web-api for more details, there is an example of a similar issue for a decimal property.
The key distinction to understand is that Guid.Empty is really a valid Guid. The only way to distinguish between the user providing a Guid (which is empty) and not providing one at all is to make it nullable, so null = not provided, and Empty = the user provided the empty Guid.
Using a Custom Annotation
If you really don't want to make your Guid nullable, you need to consider what would you do for a 'normal' value type, e.g. an integer. Rather than making it required, you'd use a Range attribute and specify that it must be > 0.
Similarly for Guids, you'd ideally have an attribute that would simply test that it is != Guid.Empty
See https://learn.microsoft.com/en-us/aspnet/core/mvc/models/validation#custom-validation for guidance on creating a custom validation atribute.

MVC3 Error message globalization

I'm really lost trying to create custom generic validation messages for my MVC3 application.
I read many tutorials and the biggest part of them suggest one of these options:
Create an App_GlobalResources folder and inside that put my custom resource, them I change global.asax, passing the string name of my resource to DefaultModelBinder.ResourceClassKey property. Change the resource's build action to "Embeded Resource".
Right click the project, then go properties, click "Resources" tab and create your custom resource. Set it's access modifier to "Public".
The first one didn't work to me, I have the following keys in my resource:
DefaultModelBinder_ValueRequired, InvalidPropertyValue, PropertyValueInvalid, PropertyValueRequired
and none of them was used when my I tried to submit and form with empty value in a required attribute of my model.
I've put this code at global.asax Application_Start method:
DefaultModelBinder.ResourceClassKey = "My_Resource_Name";
With the second method, I've created an resource with the same keys as the first one. None of them was used by default when a property is invalid or empty (I've changed the ResourceClassKey in global.asax too, but without success). But when I added some parameters to data annotation in my model:
[Required(ErrorMessageResourceType = typeof(MyResourceFile), ErrorMessageResourceName = "MyCustomKey")]
When the attribute of that data annotation is empty, my message defined with "MyCustomKey" is used!
But I really don't want to manually set this to all my attributes, I want to replace the default error messages like: "The {0} field is required."
That message is part of DataAnnotations. The default message is compiled into the DataAnnotations assembly in the resource file under System.ComponentModel.DataAnnotations.Resources.DataAnnotationsResources.resources and is RequiredAttribute_ValidationError=The {0} field is required. You can try to download the source, change that part and rebuild it.
There doesn't seem to be a simple global way of changing it. You could try this, otherwise it looks like you are stuck with adding your attribute to every field. Or use something like this:
public class SomeModel
{
[Required(ErrorMessage = "The article is required")]
public string Article { get; set; }
[StringLength(512, ErrorMessage = "Must be less than 512 characters.")]
public string URL { get; set; }
}

MVC3 Required validation, choose value for empty

I have a hidden field which is bound to a int Id in the model, it has a required attribute and some fancy ajax code to set the id client side, the problem is that zero should be acounted as empty. Now the validation will succeed even if no Id has been selected, bow can I set which value should be counted as empty? I hope i do not need to create a custom validator for it.
Thanks
It doesn't maker sense to add required attribute to a non nullable type such as Int32. Value types are always required. You could use a nullable integer instead:
[Required]
public int? SomeProperty { get; set; }

RIA service default required attribute

I have an EF4 model with table's columns doesn't allow null.
At the SL client application I always receieve the "columnName is required" because I have the binding in xaml with [NotifyOnValidationError=True,ValidatesOnExceptions=True] for the textboxes.
My questions is:
I can overide the default required errormessage at the metadata class, but how can I have it as a custom validation? I mean I don't wnat to do this at the sealed metadata class:
[Required(ErrorMessage = "Coin English Name Is required")]
[CustomValidation(typeof (CustomCoinVaidation), "ValidateCoinName")]
public string coin_name_1 { get; set; }
I want to have it inside the custom validation method that I will define for all types of errors regards that coin_name_1, as follows:
public static ValidationResult ValidateCoinName(string name, ValidationContext validationContext)
{
if (string.IsNullOrWhiteSpace(name))
{
return new ValidationResult("The Coin Name should be specified", new [] { "Coin Name" });
}
return ValidationResult.Success;
}
Why?
for two reasons :
1- Group all the validation isdie one container (for easy localization further).
2- I don't want the coin_name_1 to be displayed to the end-user, but a meanigful as "Coin English Name".
Second question:
I have a ValidationSummary control on my xaml page where all the errors are displayed but is displaying the orignal name of the column "coin_name_1" how can I chnge that to be a meanigfil also.
Best regards
Waleed
A1:
I just left the required as it is implemented right now..
A2:
I went through different sources and find this artical.
It shows how to style the validation summary:
http://www.ditran.net/common-things-you-want-know-about-silverlight-validationsummary
I am also implementing a client-side validation asyncronizly.
Regards

StringLength attribute, client side validation and a membership provider

How do I pass a value from Membership Provider (taken from web.config) to Validation Attributes in AccountModels in default MVC 3 project?
Membership.MinRequiredPasswordLength
returns value obtained from web.config and Register.cshtml view uses it:
<p>
Passwords are required to be a minimum of #Membership.MinRequiredPasswordLength
characters in length.
</p>
But it seems that ViewModel in AccountModels file have the values hard-coded in:
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "New password")]
public string NewPassword { get; set; }
So how do I pass the value from web.config to MinimumLength parameter?
You won't be able to specify an attribute property dynamically like you would like. That is why the templates have it hard-coded. The workaround to still use data annotations would be to have your view model implement IValidatableObject and have it check the password against Membership.MinRequiredPasswordLength. Another option would be to create an attribute that inherits from ValidationAttribute and checks against Membership.MinRequiredPasswordLength.
David Hayden has a post covering both of these options.
For the client side, you would need to implement IClientValidatable on the model or the custom attribute. Here is another answer that shows an example. You would also need to add the client side validation function, and you could use #Membership.MinRequiredPasswordLength inside your Razor view to pull in the value.

Resources