I have a problem with validating some data types.
There are int, short, DateTime and so on except string.
Suppose i have following property in my view model class
public int? LineNumber { get; set; }
When i input incorrect value i get mvc error "The value 'balblabl' is not valid for LineNumber."
But what if i want just out something like "Value incorrect"? Or what if i want to use other language? I have no idea how to do it(of course i can use string instead of int but it is painfull workaround)
i already tried dataannotationsextensions [DataAnnotationsExtensions.Integer(ErrorMessage = "Please enter a valid number.")] attribute. It is not working. I cannt to use custom validation attribute because of after binder convertation i get null value in all cases with incorrect value. I just cannt to do my own validation. I can to write my own binder but it looks like a joke. Really i think custom validation message is one of must have featerus and i cannt belive asp.net mvc doesnt has a simple way to do it.
I would like to add another, in my opinion, easy way to add and maintain custom error messages.
using the FluentValidation NuGet package.
It hooks up with mvc pretty easy have a look here
You can easily specify numerous rules for your models and display custom error messages that can use a resource file an example:
public class CreateProductCommandValidator : AbstractValidator<CreateProductCommand>
{
public CreateAgendaPointCommandValidator()
{
RuleFor(cmd => cmd.price)
.NotEmpty()
.WithMessage(Translations.CreateProduct_Price)
}
}
}
Documentation: FluentValidationDocumentation
Those errors are automatically added by the default model binder when it cannot parse the input string into its destination type. They are not like data annotations, where you can specify a resource instead of a harcoded string error message.
However you can use your own resource files, see this other question. Once you have created the resource file, you will update the global.asax for the default model binder to use it:
DefaultModelBinder.ResourceClassKey = "MyResources";
After a custom resource file has been set in the property ResourceClassKey of the default model binder, values will be resolved according to the following criteria (as per the MSDN):
If the property is not set, MVC uses the standard MVC resources.
If the property is set to an invalid class key (such as a resource
file that does not exist), MVC throws an exception.
If the property is set and the class key exists but the resource
names in the file do not exist in the application, MVC uses the
standard MVC resources.
If the property is set and the specified resources are available,
MVC uses the resources in the file.
If you need to know the key values for a particular message check this. For the message The value '{0}' is not valid for {1}., you will need to add a value with the key DefaultModelBinder_ValueInvalid
Related
I'm writing a REST service using Spring Boot and JPA. I need to be able to validate some of the input fields and I want to ensure I'm using a proper pattern for doing so.
Let's assume I have the following model and I also have no control over the model:
{
"company" : "ACME"
"record_id" : "ACME-123"
"pin" : "12345"
"company_name" : ""
"record_type" : 0
"acl" : ['View','Modify']
"language" : "E"
}
The things I need to do are:
Ensure the value is not empty - This seems simple enough using the #NotEmpty annotation and I can pass a message.
Ensure the value is part of a valid list of values - The example here is the language property in the model above. I want the value to be either E,F or S. This seems possible using a custom annotation (eg #ValidValue({"E","F","S"})) but is there a better/"Springy" way to do this?
Ensure the values in a list are part of a valid list of values - The example here is the acl property. Again this seems possible with a custom annotation like #ValidListValues({"View", "Modify", "Delete", "Hide"}) but same question as above.
Set a default value - From what I read, custom validator annotations are only able to validate and not modify. I would like to do something like #DefaultValue(value=5) if the value is null. Is this possible? More on this below.
Set a default value to the return of a static method - For example if the pin field in model above isn't set, I want to set it to something like Util.getRandomDigitsAsString(5).
Use values from another property - I would like to validate that one property contains the string from another property. Using the example model, I want to ensure that record_id starts with company.
I have this setup in what I believe is a standard way with the controller -> service -> DTO -> DAO -> Model. Another option I was thinking about was creating a method in the validateCreate() that would go through all of the items above and throw an exception if needed.
Thanks.
Yes, NotEmpty is the right way
You should define a Language enum. The language field of your POJO should be of type Language
Same as 2. Define an Acl enum.
Define that in your Java code. Initialize the value of the field to 5 by default. If the JSON contains a value, Jackson will set the field value to the value in the JSON. Otherwise, it will stay as 5. Or initialize the field to null, and add a method getValueOrDefault(int defaultValue) that returns the default value you want if the value is null.
Same as 4
Define a custom validator that applies on the class itself, rather than a property of the class. In the validator chec that the two related values are correct.
If I have an ApiController which has a post method which consumes a model which has data annotations for validation, how do I customize the name displayed for the validation errors? I don't really want to override the entire error message, but I do need the property in the error to be something other than the name of the property on the model type.
I've tried things like DisplayNameAttribute and DisplayAttribute, but those don't seem to apply for this.
The best solution I found for this was based on the following:
https://gist.github.com/benfoster/4016852
You have to create your own validator provider (as shown in link), and your own validator which will set up a ValidationContext with the proper displayName such that
validationContext.DisplayName = displayNameMappingFunction(metadata.GetDisplayName());
You then need to register the validator provider globally by using GlobalConfiguration.Services, or you need to create an IControllerConfigurationAttribute which will configure it just for one controller.
You do config.Services.Replace(typeof(ModelValidatorProvider), new CustomDisplayNameProvider()
I'm developing an ASP.NET Web API service, which allows users to post metadata.
In one of the data contracts that the users post, they're supposed to be able to post their own custom metadata in XML format. This is an example:
<Delivery>
<Type>Direct</Type>
<Time>12:00:01</Time>
<Format>Segmented</Format>
<CustomMetadata>
<ClientReference>R46375683</ClientReference>
<Contact>Me#There.com</Contact>
</CustomMetadata>
</Delivery>
I'm having trouble creating a data contract that successfully deserializes properly, however. For the CustomMetadata node, I have :
[DataMember(EmitDefaultValue=false)]
public XmlNode CustomMetadata { get; set; }
When it gets deserialized, I receive an exception:
"Collection type 'System.Xml.XmlNode' cannot be deserialized since it
does not have a valid Add method with parameter of type
'System.Object'."
I don't fully understand why it's trying to "Add" anything to the XmlNode, but for whatever reason, it's failing. Is there an alternative for doing this kind of thing, such as deserializing to a different type? I tried deserializing to a string, but that gave an exception too.
Data Contract serialisation only supports primitives and a few special types. You must use XmlElement instead of XmlNode.
Try:
[DataMemeber]
public XmlElement CustomMetadata { get; set; }
See http://msdn.microsoft.com/en-us/library/ms733127.aspx
Can you try using XmlElement instead of XmlNode? I believe the serializer only special cases elements on deserialization. XElement should work too.
We are developing a web application based on JSF (v2.0) framework. We need to have custom validations in our application. We decided to extend the JSF validation framework by implementing the Validator class.
So let us say that we have multiple input fields which needs to be validated. These input fields are First Name, Last Name, Email Address. We need the user to enter information in these fields. And email address field will have two validations - Required and isValidEmailAddress.
We should be able to use the custom Required validation in First Name, Last Name and Email Address fields. But each time I want different error messages to be displayed for each field. For example in case of First Name, I want to display First Nameis required. In case ofLast nameI want to displayLast name is required`.
How can I reuse the same Required validation implementation for multiple fields but with different error message? Is it possible to do that in JSF? Could you please let me know?
First of all, you don't need to write your own validation logic for required input in JSF. It's one of the basic amenities provided by the framework itself.
JSF's validation framework is cleanly abstracted from messages related to validation, so the two don't have to depend on each other. Your options:
Each input component has a validatorMessage attribute that allows you specify the text/string that will be displayed to the user on validation error. For your specific use case, JSF has gone one step further to specify the required and requiredMessage attribute for input components; to enforce required input and show messages specifically for required input validation respectively. What this means in your use case is that you don't need to write custom validation logic for required input.
By principle of better design you can configure all your desired validation/conversion error messages in a resource bundle (example here) and reference the entries in the resource bundle within your jsf view.
Implementing the validator interface requires you implement the validate method with the following signature
public void validate(FacesContext ctxt, UIComponent comp, Object value) throws ValidatorException
comp refers to the component being validated from which you can get it's Class, clientId etc. value will provide the submitted value from the component
I'm creating an MVC 3 application that needs to establish data validation rules at runtime based on external data (e.g. Required, MinimumLength, MaximumLength). It seems natural to use Data Annotations in MVC 3, however the property attributes that provide validation metadata are set at compile-time.
Is there a pattern to use Data Annotations with metadata provided at runtime?
Example:
public string Text { get; set; }
public void SetIsRequired(string propertyName, bool required)
{
// Somehow find the property 'propertyName' and create/remove a RequiredAttribute
// on that property
}
...
SetIsRequired("Text", true);
I'm aware of TypeDescriptor, but don't see an option to modify attributes of a property of an instance (only class level attributes on an instance, or property level attributes for a type).
It seems natural to use Data Annotations in MVC 3
Not for me. I never really liked data annotations due to their declarative nature. And doing validation in a declarative way limits capabilities. I have always liked and use FluentValidation.NET.
You could probably use the IDataErrorInfo interface (which MVC can consume) to write your custom, dynamic, validation rules.