Not getting data-val attributes for GUID - c#

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

Related

How do I validate some fields some of the time?

I'm using C# in .Net-Core MVC and I have a form that users will need to fill out.
All of the fields that are shown on the page are required to be filled out. The issue I'm running into is that some of the fields on the form are hidden and others are displayed based on choices previously made on the form.
If I put the [Required] tag on all of the fields in the model, when I validate the ModelState, it flags the not displayed fields as invalid.
Is there a way that when I try to validate the ModelState, I can validate only the fields displayed on the page and ignore the fields that have been hidden?
Thanks.
Unfortunately the [Required] works globally in MVC.
You will need to develop your own validation attributes. Hopefully someone already did it but for MVC with .NET Framework (see the code here):
For validations that has the form of: “Validate this field only when
this other field has certain value”, I have coded 3 attributes:
RequiredIf, RangeIf and RegularExpressionIf that inherints from
ValidationAttribute.
Now you will need to translate it in order to work for .NET Core.
If you are looking for a more generic solution, the Web Forms framework has a very good concept of Validation group. It allows you to validate - or not - logically grouped properties.
If I put the [Required] tag on all of the fields in the model, when I
validate the ModelState, it flags the not displayed fields as invalid.
Of course cuz you set a parameter "Required". Disable that parameter from fields what can be not displayed or make nullable

Scaffolder creates DATETIME instead of DATE, even when explicitly set to DATE by data annotations

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! :)

Custom Data Annotations ( DataType )

Is it possible to add new datatypes to the existing DataAnnotations (I'm not looking for a validator but a raw data type). For example
Currnetly you have
[DataType(DataType.Html)]
public string Footer {get; set;}
And into the mix you can add ~Views/Shared/EditorTemplates/Html.cshtml
I'd like to be able to add [DataType(DataType.CSS)] I know in theory I could use a UIHint for adding a specific view, but if possible I'd like to do it at an even earlier stage and specify the datatype rather than relying on UI Hints.
Any pointers would be greatly appreciated. A Quick search of S.O seems a lot of answers around Custom meta-data types, custom validators, and multiple datatyps but I can't seem to find one for adding a new core data-type.
DataType has a second constructor that takes a string. However, internally, this is actually the same as using the UIHint attribute.
Adding a new core DataType is not possible since the DataType enumeration is part of the .NET framework. The closest thing you can do is to create a new class that inherits from the DataTypeAttribute. Then you can add a new constructor with your own DataType enumeration.
public NewDataTypeAttribute(DataType dataType) : base(dataType) { }
public NewDataTypeAttribute(NewDataType newDataType) : base (newDataType.ToString()) { }
Yes, you can. DataTypeAttribute has a constructor that accepts string.

View model properties has changing validation rules at run time

I'm new to C# MVC and I'm trying to add some dynamic validation checks to my view models that are used in a form. For example, I have a string property called FirstName. I can add the attribute StringLength(10) and Required() to it.
My problem is, depending on some other field, the FirstName StringLength could vary from 10 to 20, etc. I still want to use the MVC validations but be able to modify it. I know that attributes are bound to the class so maybe I'm using the wrong thing.
I want the abilities for attribute validation but have it modifiable at run time. Is this possible?
The values in an attribute have to be literals. You can still use attribute based validation, but you will need to use the CustomValidation tag and point it at a method to use. If it depends on multiple fields in the object, you will want to put this on the class rather than the property.
It seems you can add validation attributes at runtime by implementing DataAnnotationsModelValidatorProvider:
Dynamic Attributes # forums.asp.net

Unobstructive client validation error

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?

Categories

Resources