Custom error message not working for DateTime validation in asp net mvc 3 - asp.net-mvc-3

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

Suppress implicit required attribute

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?

MVC Model doesn't catch all model errors

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.

MVC dataannotations decimal datatype validation

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

Get full name of Complex Type from ModelClientValidationRequiredIfRule method in custom ValidationAttribute

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.

Model Validation / ASP.NET MVC 3 - Conditional Required Attribute

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/

Resources