I am currently using MVC 1.0 and .NET 3.5. I am using DataAnnotations to validate my model. I'm trying to add use the RegularExpression to validate a Postcode. I have stored my Regex in the resource file as many models will use it, when I try the following:
[RegularExpression(Resources.RegexPostcode, ErrorMessage="Postcode format invalid")]
public string Postcode { get; set; }
I get the following error when I build:
An attribute argument must be a
constant expression, typeof expression
or array creation expression of an
attribute parameter type.
Is there any way to use values from a Resource file as the regex or will I need to enter the actual regex string into every model that has a postcode?
Thanks
I would suggest making your own ValidationAttribute. This will keep the regex in one place as well as the error message.
class PostcodeAttribute : RegularExpressionAttribute
{
public PostcodeAttribute() : base("your regex")
{
this.ErrorMessage = "Postcode format invalid";
}
}
Can't leave a comment on the accepted answer as I don't have enough rep.
This accepted answer worked for me, but needed a tweak to work with the unobtrusive javascript validation. Needed the IClientValidatable bits from this answer: https://stackoverflow.com/a/18041534/1714585
Related
If I have a property in a view model like:
[DataType(DataType.DateTime)]
public DateTime? MyDate{ get; set; }
And a validation rule like this:
public class YourDetailsViewModelValidator : AbstractValidator<YourDetailsViewModel>
{
public YourDetailsViewModelValidator()
{
RuleFor(x => x.MyDate)
.InclusiveBetween(startDate, endDate)
.WithMessage("error");
}
}
Why does the error fire regardless of what date is input?
I did see a similar thing was happening enter link description herebut the answer was ultimately accepted so I'm hoping it can be made to work properly.
Error can be explained by difference in jquery.validate plugin date formatting and MVC helpers formatting. Just look in html generated by your view, and use
[DisplayFormat(DataFormatString="...")] // format string instead of dots
to make data-val-min and data-val-max attributes conform input value format (if they not, of course).
If value and validation attributes format are the same, but validation still fails - make sure that jquery.validate has appropriate format. In this case you should change ASP.NET MVC application culture to conform jquery.validate format, or vice versa — change jquery.validate format to conform application.
Similar questions asked on SO:
First
Second
.NET date formatting options available here.
I am trying to realize valition on data type. I have used DataAnnotations, but for data type it's not showing customized message
for example when I' am trying enter string data into int typed field. How I can customize messages in this case?
If I had to guess, you sound like you want a custom message to display when validating one or more fields in your model. You can subclass the DataAnnotations.ValidationAttribute class and override the IsValid(object) method and finally setting a custom ErrorMessage value (where ErrorMessage already belongs to the ValidationAttribute class)
public class SuperDuperValidator : ValidationAttribute
{
public override bool IsValid(object value)
{
bool valid = false;
// do your validation logic here
return valid;
}
}
Finally, decorate your model property with the attribute
public class MyClass
{
[SuperDuperValidator(ErrorMessage="Something is wrong with MyInt")]
public int MyInt { get; set; }
}
If you're using out-of-the-box MVC3, this should be all you need to propertly validate a model (though your model will probably differ/have more properties, etc) So, in your [HttpPost] controller action, MVC will automagically bind MyClass and you will be able to use ModelState.IsValid to determine whether or not the posted data is, in fact, valid.
Pavel,
The DataAnnotations DataType attribute does not affect validation. It's used to decide how your input is rendered. In such a case, David's solution above works.
However, if you want to use only the built-in validation attributes, you probably need to use the Range attribute like this:
[Range(0, 10, ErrorMessage="Please enter a number between 0 and 10")]
public int MyInt { get ; set ;}
(Of course, you should really be using the ErrorMessageResourceName/Type parameters and extract out hard-coded error message strings into resx files.)
Make sure to let MVC know where to render your error message:
<%= Html.ValidationMessageFor(m => m.MyInt) %>
Or you can just use EditorForModel and it will set it up correctly.
I don't think this has been answered because I have the same issue.
If you have a Model with a property of type int and the user types in a string of "asd" then the MVC3 framework binding/validation steps in and results in your view displaying "The value 'asd' is not valid for <model property name or DisplayName here>".
To me the poster is asking can this message that the MVC3 framework is outputting be customized?
I'd like to know too. Whilst the message is not too bad if you label your field something that easily indicates an number is expected you might still want to include additional reasons so it says something like:
"The value 'asd' is not valid for <fieldname>; must be a positive whole number."
So that the user is not entering value after value and getting different error messages each time.
how can I use a Required Validation in a property Prop2 only if the Prop1 is true?
Ex:
public bool Prop1 { get; set; }
[Required] // I need this validation only if the Prop1 is true.
public string Prop2 { get; set; }
Any idea? I need on client and server side.
Thanks
You could use MVC FoolProof Validation framework
It has useful feature like
[RequiredIf]
[RequiredIfNot]
[RequiredIfTrue]
[RequiredIfFalse]
[RequiredIfEmpty]
[RequiredIfNotEmpty]
[RequiredIfRegExMatch]
[RequiredIfNotRegExMatch]
[Is]
[EqualTo]
[NotEqualTo]
[GreaterThan]
[LessThan]
[GreaterThanOrEqualTo]
[LessThanOrEqualTo]
Hope this would help you!
There are two parts to this. First, you have to write a required attribute that's only required if the other property meets your criteria.
You'd have to do something like:
public class RequiredComparerAttribute : RequiredAttribute
{
public OtherProperty { get; set; }
public override bool IsValid(object value)
{
// TODO: use reflection to validate other property as PropertyInfo
// or validate it's value after it is decided to be valid
foreach (ValidationAttribute va in property
.GetCustomAttributes(typeof(ValidationAttribute), true)
.OfType<ValidationAttribute>())
{
if (!va.IsValid(value))
{
return false; // not required
}
}
return true; // required
}
}
Then, in Application_Start in the Global.asax, you'll have to register the validator, which you can just reuse the RequiredAttribute's validator:
DataAnnotationsModelValidatorProvider
.RegisterAdapter(typeof(RequiredComparerAttribute),
typeof(RequiredAttributeAdapter));
If you want to add your own validator, you'll have to write a custom validator. Phil Haack has an example on his blog: http://haacked.com/archive/2009/11/19/aspnetmvc2-custom-validation.aspx
Edit: Take a look at CompareAttribute in .NET Reflector for a sense of how to get the value of the OtherProperty. CompareAttribute also implements IClientValidatable to provide those validation rules needed on the client side.
I don't think CompareAttribute will work for you because you have to validate that a value is required based on content of another property, not compare the equality of two properties.
Edit2: What does the Validation provider do?
It adds rules to the form and provides messages for those rules. You can see exactly how the RequiredAttributeAdapter does this by downloading the MVC 3 source. To understand what it does on the client side, you can open the MVC 3 page in Google Chrome, hit CTRL+SHIFT+J to bring up a developer tools window and enter:
$('form:first').data().unobtrusiveValidation.options
The rules object inside options specifies how to validate each item and the message object specifies the error message that will be displayed for each validation error.
Edit3: Full example
Since answering this question, I've written a blog post with a full example of creating a custom attribute on the client (unobtrusive validation) and server. The blog post is here. This example is for a 'contains' attribute, but it should be pretty easy to modify to become a required comparison.
You can write a custom validator do to this job.
Let me know if you need help to do it.
I have an issue with the implementation of VAB. We are using ASP.NET MVC 1.0
I have a property "First Name" and we want to have 2 validations.
Not Null Validator
RegEx Validator (to stop some characters)
Now if I leave it blank then it gives me the error message from both the validator.
If the First name is blank I only want Not Null to show the error details
If the First name is not blank then i was the RegEx to get executed and if there are any invalid characters then i want to stop them.
Please guide me here
Thanks !
The Not Null Validator is not going to pick it up because the string is not null - it is an empty string. Have a look at this post: http://geekswithblogs.net/michelotti/archive/2008/06/12/122836.aspx
When you're using Enterprise Library 5.0, you can mix VAB attributes and DataAnnotation attributes (because VAB now extends DataAnnotations). When you decorate your property as follows, your problem is solved:
[System.ComponentModel.DataAnnotations.Required]
[EnterpriseLibrary.Validation.Validators.RegexValidator("...")]
public string LastName { get; set; }
my object has field with data type int. when i put in html form in this textbox letter not number the validator say- The field must be a number. how can i change this messages like this
[Required(ErrorMessage = "Введите название")]
[DisplayName("Название")]
public int age { get; set; }
I haven't found a clean way to achieve this using Data Annotations. One way would be to write a custom model binder but this seems like a lot of work to do for such a simple task.
Another way to achieve this is to add an App_GlobalResources folder to your ASP.NET application. Add a resource file called Messages.resx containing a PropertyValueRequired string resource.
PropertyValueRequired = "Some custom error message"
In your Application_Start register the resource class key:
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
DefaultModelBinder.ResourceClassKey = "Messages";
}
Note that ASP.NET MVC 2 uses the PropertyValueInvalid instead of PropertyValueRequired resource key.
IMO using Data Annotations to perform validation logic is limited (maybe in .NET 4 this will change). If you want to have full control over the validation logic I would recommend you using a validation library such as Fluent Validation or xVal.
I ran into the same problem and worked around it by specifying a RegularExpression that only allows positive natural numbers.
[Required(ErrorMessage = "Введите название")]
[DisplayName("Название")]
[RegularExpression(#"^[0-9]+$", ErrorMessage = "Поле возраст не является числом")]
public int age { get; set; }
Not sure if there are any downfalls to this solution. It seems to work fine for me.
PS: If you don't want to allow leading zeroes use "^[1-9]+[0-9]*$".
In retrospect: I have to admit though it's a bit weird to add a regular expression to an integer.