I have a ViewModel with a String property and the following Data Annotation :
Edit to work with string
[DataType(DataType.Date, ErrorMessage="Not Working !!!")]
public String StringBirthDate1 { get; set; }
That's my view
#Html.EditorFor(model => model.StringBirthDate1 )
#Html.ValidationMessageFor(model => model.StringBirthDate1)
If I run my application and put an invalid Date like '---' or 29.02.1900 I don't get any validation error !
Ok I've given up trying to use built-in MVC tools for data validation !
I did a custom Validation Attribute :
public class ValidDateStringAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
DateTime dtout;
if (DateTime.TryParse(value.ToString(), out dtout ))
{
return true;
}
return false;
}
}
Here is my View Model decorated with the custom attribute :
[ValidDateString(ErrorMessage="Invalid date format")]
public String BirthDate1 { get; set; }
Works like a charm :-)
It seems to me, that [DataType(DataType.Date, ErrorMessage="Not Working !!!")] working when it attached to string property. Try to use:
[DataType(DataType.Date, ErrorMessage="Not Working !!!")]
puplic string StringBirthDate1{get;set;}
public DateTime BirthDate1
{
get{return DateTime.Parse(StringBirthDate1);}
set{StringBirthDate1 = value.ToString();}
}
I didn't like any of the solutions I found so I kept poking at possibilities until I came up with one I do like. I added a regular expression validator utilizing the regular expression from this article: http://answers.oreilly.com/topic/226-how-to-validate-traditional-date-formats-with-regular-expressions/
[Required(ErrorMessage = "Birthdate is required. [MM/DD/YYYY]")]
[RegularExpression(#"^([1-9]|0[1-9]|1[0-2])[- / .]([1-9]|0[1-9]|1[0-9]|2[0-9]|3[0-1])[- / .](1[9][0-9][0-9]|2[0][0-9][0-9])$", ErrorMessage = "Birthdate must be in MM/DD/YYYY format.")]
public Nullable<DateTime> Birthdate { get; set; }
The result is, if the field is blank I get the required error message and if anything is in the field, but it is not a valid date, I get the regular expression message.
I might add that it seems very silly that [DataType] doesn't accept an error message. I tried exactly like the original author of this thread. That would have been logical and intuitive.
Related
Consider the following simple model:
public class TestClass {
[MyRequired(ErrorMessage = "Some error message")]
public int TestVariable { get; set; }
}
This will implicitly add the [Required] attribute and the rendered html will contain data-val attributes for both [Required] and [MyRequired].
I found 2 possible solutions:
// Solution #1 (.net 5 only)
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
// Solution #2
services.AddControllers(options => options.SuppressImplicitRequiredAttributeForNonNullableReferenceTypes = true);
Unfortunately the first solution is not available for .net 6 and the second solution doesn't seem to work (propably because int is a value type and not a reference type?)
Finally I was able to solve this by making the TestVariable nullable:
public int? TestVariable { get; set; }
Not sure if this is good practice. Is there any way to disable this behavior globally without making everything nullable?
This is part of a an MVC model class:
[Required]
[StringLength(2, ErrorMessage = "Two characters.")]
public string StateProvince { get; set; }
If I submit my form with a blank StateProvince, I will get an error message. If I submit it with one character in StateProvince, no problem. Here's how I get back error messages:
if (!ModelState.IsValid)
{
MyMessage ErrMsg = new MyMessage();
ErrMsg.StatusCode = 101;
ErrMsg.StatusMsg = string.Join("; ", ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage));
return "[" + JsonConvert.SerializeObject(ErrMsg) + "]";
}
MyMessage is structured like so:
public class MyMessage
{
public int StatusCode { get; set; }
public string StatusMsg { get; set; }
}
Am I right to conclude that the StringLength decoration only serves to create client-side validation in the html input field?
Since I'm coding the HTML myself and not using Asp.Net to generate it, then should I just omit the StringLength decoration on the model field and instead write server-side validation code for that in the controller? (And that violates MVC, right?)
Oops! Sorry! StringLength was working. It only prevents excess characters, not minimum number of characters. I know there's code for enforcing an exact length; I've seen it before and will look it up.
My application is made on ASP.NET MVC4.And i am using MVC dataannotations validations in my viewmodel classes.
I have one decimal type column.And i am using below regular expression to validate it.
[RegularExpression(#"^\$?([0-9]{1,3},([0-9]{3},)*[0-9]{3}|[0-9]+)(.[0-9][0-9])?$",ErrorMessage = "Amount is invalid.")]
public decimal Amount { get; set; }
And with the help of above regular expression its working well.
But I want to add one more condition there.Which is if someone enters number like:
12.
445.
Then it should accept it and also should adds .00 means (12.00,445.00) automatically.
FYI, I have changed the above regular expression like this:
[RegularExpression(#"^\$?([0-9]{1,3},([0-9]{3},)*[0-9]{3}|[0-9]+)(.[0-9][0-9]|.)?$",ErrorMessage = "Amount is invalid.")]
And by this its accepting the numbers like:
12.
445.
But due to MVC datatype decimal filed its giving the another validation message..
Can anyone suggest me how i can manage that?
I'd offer using shadow field:
class myModel
{
...
public decimal Amount { get; private set; }
[RegularExpression(#"^\$?([0-9]{1,3},([0-9]{3},)*[0-9]{3}|[0-9]+)(.[0-9][0-9])?$",ErrorMessage = "Amount is invalid.")]
public string AmountStringed //use this field on your form input
{
get { return Amount.ToString(); }
set { Amount = decimal.parse(value); } //assign Amount
}
}
So you don't have to do any hacks with either client or server side valiedations
I am using the example at The Complete Guide To Validation In ASP.NET MVC 3 to create a RequiredIf validation attribute (it's about 1/3 down the page under the heading of "A more complex custom validator"). It all works fine with the exception of one scenario, and that is if I have the need to validate against a complex type. For example, I have the following model:
public class MemberDetailModel
{
public int MemberId { get; set; }
// Other model properties here
public MemberAddressModel HomeAddress { get; set; }
public MemberAddressModel WorkAddress { get; set; }
}
public class MemberAddressModel
{
public bool DontUse { get; set; }
// Other model properties here
[RequiredIf("DontUse", Comparison.IsEqualTo, false)]
public string StreetAddress1 { get; set; }
}
The problem is that when the attribute validation for the StreetAddress property is rendered, it get's decorated with the attribute of data-val-requiredif-other="DontUse". Unfortunately, since the address is a sub-type of the main model, it needs to be decorated with a name of HomeAddress_DontUse and not just DontUse.
Strangely enough, the validation works fine for server-side validation, but client-side unobtrusive validation fails with an JS error because JS can't find the object with a name of just "DontUse".
Therefore, I need to find a way to change the ModelClientValidationRequiredIfRule method to know that the property it is validating is a sub-type of a parent type, and if so, prepend the ParentType_ to the "otherProperty" field (e.g. otherProperty becomes HomeAddress_DontUse.
I have tried passing in typeof(MemberAddressModel) as a parameter of the attribute, but even when debugging the attribute creation, I can't seem to find any reference to the parent type of HomeAddress or WorkAddress from that type.
Based on the suggestion from The Flower Guy, I was able to come up with the following which seems to work. I simply modified the following in the customValidation.js file:
jQuery.validator.addMethod("requiredif", function (value, element, params) {
if ($(element).val() != '') return true;
var prefix = getModelPrefix(element.name); // NEW LINE
var $other = $('#' + prefix + params.other); // MODIFIED LINE
var otherVal = ($other.attr('type').toUpperCase() == "CHECKBOX") ? ($other.attr("checked") ? "true" : "false") : $other.val();
return params.comp == 'isequalto' ? (otherVal != params.value) : (otherVal == params.value);
});
I also added the following method to that file (within the JQuery block so as to be only privately accessible):
function getModelPrefix(fieldName) {
return fieldName.substr(0, fieldName.lastIndexOf(".") + 1).replace(".","_");
}
Cannot do it exactly right now, but the problem is in the client javascript function:
jQuery.validator.addMethod("requiredif" ...
The js is not sophisticated enough to cope with complex view models where there may be a model prefix. If you take a look at Microsoft's jquery.validate.unobstrusive.js (in the Scripts folder over every MVC3 application), you will find some useful methods including getModelPrefix and appendModelPrefix. You can take a similar approach and change the requiredIf validation method - take a look at the equalto method in jquery.validate.unobstrusive.js for a helping hand.
I'm having trouble with my ASP.NET MVC 3 application. I have 2 propertiesin my model whereby I only want 1 of them required in my view based on whichever one is empty. So for example, if I enter a phone number then email is no longer required and vice versa, but if I leave both empty, then either 1 should be required, below is my model:
[Display(Name = "Contact Phone Number:")]
[MaxLength(150)]
public string ContactPhoneNumber { get; set; }
[Display(Name = "Contact Email Address:")]
[MaxLength(100)]
public string ContactEmailAddress { get; set; }
Would I need to create a custom attribute to validate my model and if so, how would I achieve this?
You can implement IValidatableObject on your class and provide a Validate() method that implements your custom logic. Combine this with custom validation logic on the client if you prefer to ensure that one is supplied. I find this easier than implementing an attribute.
public class ContactModel : IValidatableObject
{
...
public IEnumerable<ValidationResult> Validate( ValidationContext context )
{
if (string.IsNullOrWhitespace( ContactPhoneNumber )
&& string.IsNullOrWhitespace( ContactEmailAddress ))
{
yield return new ValidationResult( "Contact Phone Number or Email Address must be supplied.", new [] { "ContactPhoneNumber", "ContactEmailAddress" } );
}
}
}
To get everything working at client side you'll need to add the following script to your view:
<script type="text/javascript">
$(function() {
$('form').validate();
$('form').rules('add', {
"ContactPhoneNumber": {
depends: function(el) { return !$('#ContactEmailAddress').val(); }
}
});
});
</script>
Annotation-based conditional validation can be defined using ExpressiveAnnotations:
[RequiredIf("ContactPhoneNumber == null",
ErrorMessage = "At least email or phone should be provided.")]
public string ContactEmailAddress { get; set; }
[RequiredIf("ContactEmailAddress == null",
ErrorMessage = "At least email or phone should be provided.")]
public string ContactPhoneNumber { get; set; }
Here is a MSDN blog entry about conditional validations: http://blogs.msdn.com/b/simonince/archive/2011/02/04/conditional-validation-in-asp-net-mvc-3.aspx
I know you already have a solution, but I had a similar situation, so maybe my solution will prove helpful to someone else. I implemented a custom attribute with client-side validation. Here is my blog post: http://hobbscene.com/2011/10/22/conditional-validation/