I am using asp.net mvc 3 and I keep getting the following error.
Validation type names in unobtrusive
client validation rules must be
unique. The following validation type
was seen more than once: number
I have no clue as I have this
#Html.TextBoxFor(x => x.Mark)
// my viewmodel
[Required(ErrorMessage = "Message")]
[Number(ErrorMessage = "Message")]
public decimal Mark { get; set; }
If I change it from a decimal to string it will not complain. What is going on?
Edit
I think it is because of this the [Number(ErrorMessage = "Message")] annotation. I am using this library Data annotation extensions
It seems not not like that I am using decimals. Anyone know why?
If you are using type decimal, you do not need to use the [Numeric] attribute because MVC already sees you are using a numeric type and injects that in for you (which is causing the error). When you change to a string, the [Numeric] is then needed to tell the validation how you want that string to work.
In the next version of DataAnnotationsExtensions, I'll change the [Numeric] attribute so it won't collide with the MVC version in this case. But for now, removing the [Numeric] attribute will be just fine because [Numeric] on a numeric type is redundant anyway.
You probably have multiple model validators which are adding the same client rule twice, are you using a custom validatiOn provider?
Required will become duplicate since Mark is not nullable. I would change it to be decimal?
Related
I am wanting to validate that a property value is set to a specific text. I came across [validation] (https://www.tutorialsteacher.com/mvc/implement-validation-in-asp.net-mvc) and saw how there are many options such as Required which is very helpful. But I do not see one to ensure that a property has a specific value. Is there a way I can do that using data annotations? Is regular expression for that?
i.e.
ClassName property must be set to "science". Is there a data annotation for property values? Is regular expression for that?
public class Student{
[DataAnnotation("science")]
public string ClassName{ get; set; }
}
I have searched over a few articles and still cannot find the solution to my problem. Would like to know if this is possible with data annotations?
You need to Use CustomValidationAttribute. Please refer below
https://learn.microsoft.com/en-us/previous-versions/aspnet/cc668224(v=vs.100)
https://www.codeproject.com/Tips/5257153/How-to-Create-Custom-Validation-Attribute-in-Cshar
https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations.customvalidationattribute?view=netframework-4.8
Basically, these attributes will have Isvalid function. In you case you can put the validation as Property value == science
I'm working on a bigger project and we have many views and almost all of them have a SelectList or more, whose value is a GUID. The viewmodel works fine and server side validation as well, the problem is that the HTML select element does not get any data-val attributes, we are using Html.DropDownListFor. It works fine when the value is short, string etc but not GUID.
Is there a way to get data-val attributes without adding an ValidationAttribute to all GUID properties in the viewmodels? Because there are a loot of them.
What worked for me in the end:
I got on the right track with Stephen Muecke's answer: we are using our own RequiredAttribute:
public class LocalizedRequiredAttribute : RequiredAttribute
{
public LocalizedRequiredAttribute()
{
ErrorMessageResourceName = "Required";
ErrorMessageResourceType = typeof (Resources.ErrorMessages);
}
}
But this does not add any client side validation attributes like the basic [Required] does, but it was easy to fix. Just add this code to your Application_Start():
DataAnnotationsModelValidatorProvider.RegisterAdapter(
typeof (LocalizedRequiredAttribute),
typeof (RequiredAttributeAdapter));
And now you will get data-val=true data-val-required="message".
Solution found here: https://stackoverflow.com/a/12573540/1225758
No data-val-* attributes are rendered because there are no jquery.validate.unobtrusive adaptors for GUID. The only one you could get out of the box is data-val-required (and the associated data-val) if you were to make the property nullable and add the [Required] attribute.
If you want some client validation you could use a [RegularExpression] attribute (not tested but I think ^[A-Za-z0-9]{8}-[A-Za-z0-9]{4}-[A-Za-z0-9]{4}-[A-Za-z0-9]{4}-[A-Za-z0-9]{12}$ should work).
However it seems unnecessary since you are using #Html.DropDownListFor() and (I assume) your building a SelectList on the controller which would contain only GUID's for the SelectListItem.Value property (why would you render an option which is not valid - other than perhaps a "--Please select--" label option for use with a [Required] attribute?).
Firstly, I would want to know what the problem is with having multiple GUID data annotations on your model properties?
Secondly I would say that it is far clearer and readable to other developers working on the project to have explicit validation going on with data annotations on each property than it is to have some "non-standard" validation voodoo going on.
You could probably achieve this with action filters (look for any properties of type Guid) but I think this will make the use/specification of your models less expressive of their intentions and simply confuse.
Guids have dashes in content and may occur problems. You may try to use .ToString('N') at the end of the Guids where they are being generated to remove dashes. Or you may write a jquery hack to add escape characters before dashes on client side. Or even more; try to implement your own guid validation approach as here: How to test valid UUID/GUID?
Or even even more, you can try to implement your own guid annotation attribute as here:
Validation of Guid
I have encountered a nuisance where the MVC scaffolder sets the data type in the database to DATETIME when I in my model have set the datatype to DATE using data annotations. Any clues why?
[DataType(DataType.Date)]
public DateTime? my_date { get; set; }
I am using VS2012, MVC 4.5.
Thanks!
I believe the DataTypeAttribute makes sense only in regards of the UI representation of the field (when using the helper methods DisplayFor and EditorFor, for example).
Quoting from MSDN (highlight is mine):
The DataTypeAttribute attribute lets you mark fields by using a type that is more specific than the database intrinsic types. For example, a string data field that contains e-mail addresses can be attributed with the EmailAddress type. This information can be accessed by the field templates and modify how the data field is processed.
It seems there is no reference to the actual database type used.
EDIT: Fluent Mapping?
Apparently EF also has the option of setting the DataType for a given property: msdn.microsoft.com/en-us/data/jj591617.aspx#1.10. I honestly never used it so if you wish to investigate and edit this answer with your findings it would be great! :)
Suppose if I have an Annotation like the following
[DisplayFormat(DataFormatString = "{0:#.00#}", ApplyFormatInEditMode = true)]
It works great. But suppose I want to replace the DataFormatString in real time i.e. some times like this {0:#.00#} and sometimes {0:#.000#} based on some application settings the user chooses. Is there a way to do that?
I tried storing the format string in a global variable, but it gives me the following error.
An attribute argument must be a constant expression, typeof expression
or array creation expression of an attribute parameter type
If I make the global variable constant it works but then the purpose is lost. Any advice on a work around?
Basically I would like to give the users an option to set the decimal spaces universally with out having to implement the feature on a per View/Controller basis.
I know I can put the culture using NumberFormat.CurrencyDecimalDigits. But this will ignore Zeros after the decimal.
Attribute requires constant string, you can't change that. Also this attribute does not provide ability to provide resource name. So, I think best way to you is creating DisplayTemplate and EditorTemplate for this property.
[UIHint("Bar")]
public decimal Bar { get; set; }
And in Bar template you can change format based on some application settings chosen by user:
#model decimal
#Model.ToString(HttpContext.Current.Session["format"].ToString())
There is a good library called MvcExtensions, one of it's feature is fluent metadata configuration. It allows you to construct model metadata fluently instead of DataAnnotations.
Using this library, you may accomplish your task:
Configure(x => x.Payment)
.Format(() => ConfigurationManager.DataFormatString)
In my model I have a particular field that is annotated in the following manner:
[DataType(System.ComponentModel.DataAnnotations.DataType.Text)]
[RegularExpression("[0-9]{1,10}", ErrorMessage = "The stated Attempt Id is invalid!")]
public long? AttemptId { get; set; }
When I enter incorrect data in the Attempt ID it is giving me the following error message in the Model State:
The value 'cbcbxcb' is not valid for AttemptId.
I have other field with similar error messages but they're of type string instead of long? and the correct error message is being displayed in those cases when an invalid value is given. Why isn't the message for the 'long?' being used? I'm displaying my errors using the folowing literal tag in the page.
<%: Html.TValidationSummary() %>
EDIT: I have attempted to change the validation in the model to the following:
[Required(ErrorMessage="The stated Attempt Id is invalid!", AllowEmptyStrings=true)]
This however is still incorrect. Firstly, I need to allow the field to be left empty, and when I do it's giving me the 'The stated Attempt Id is invalid!' error message. Secondly when I do enter invalid data in the field it's reverting back to its old bad error message.
The RegularExpression validation attribute only works with string types. To get a custom error message, use the Required validation attribute instead and put your own custom error message in.
If your model parameter isn't mandatory, you could perform the validation within the controller and add your own custom message using the ModelState.AddModelError method - this is a bit of a hack, though.
its probably the fact that MVCs binding can't even cast the input value into the correct type, so it already knows the value must be invalid.
You should be using FluentValidation
The built in validation stuff using attributes is brittle and nasty - to say the least.