Model validation attribute [Required] doesn't accept a string of all spaces - validation

I'm working with ASP.Net MVC 4 website project.
When I set the attribute Required for a model property.
[Display(Name = "Some Model Property:")]
[Required]
public string SomeModelProperty{ get; set; }
This will mark the input field to be red when its value is empty.
My issue is that this field is also marked red when its value is all spaces
I want to allow input value to have all spaces only for a Required property.
How can I get to that?

You should use:
[Required(AllowEmptyStrings = true)]
And if the length of the string matters add:
[MinLength(1)]

You could create your own ValidationAttribute to do the job.
public class MostlyRequiredAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
return value != null && !string.IsNullOrEmpty(value.ToString());
}
}
[Display(Name = "Venue Assigned Abstract Tracking Number:")]
[MostlyRequired]
public string SomeModelProperty{ get; set; }

Related

MVC4 not displaying DefaultValues

In my model:
[Required]
[DefaultValue("Some text ...")]
public string SomeValue{ get; set; }
In my view:
#Html.TextBoxFor(model => model.SomeValue)
At start the textbox is empty, I'd like it to contain the default value.
Thank you if you can help me.
You need to set the value in the constructor of your model...
public class MyModel {
public MyModel() {
SomeValue = "Some text...";
}
[Required]
[DefaultValue("Some text ...")]
public string SomeValue{ get; set; }
}
The DefaultValueAttribute isn't for setting the value - it is for comparing it later. For example, when the model is mapped from the user input, you can check if SomeValue has been entered or not because you can check whether it is the same as DefaultValue.
http://support.microsoft.com/kb/311339
[...] However, the DefaultValue attribute does not cause the initial value to be initialized with the attribute's value.

Required attribute not displaying

Public Class Duration
{
[Required]
Public DurationUnit Unit
[Required]
Public int Length
}
Public Class Employee
{
[RequiredAttribute]
public virtual Duration NotificationLeadTime { get; set; }
}
The fields Unit and Length, when not suplied are getting highlighted in Red but the error message is not getting displayed.
I tries also giving [Required(ErrorMessage="sadfdsf")],but this is also not working.
I also tried inheriting the class with IValidatableObject but that also didn't work.
How to display the error message ?
You should use properties, not fields:
public class Duration
{
[Required]
public DurationUnit Unit { get; set; }
[Required]
public int Length { get; set; }
}
In order to display the corresponding error message use the Html.ValidationMessageFor helper.
For example:
#Html.EditorFor(x => x.NotificationLeadTime.Unit)
#Html.ValidationMessageFor(x => x.NotificationLeadTime.Unit)
By the way it doesn't really make sense to decorate a non-nullable type such as int with the [Required] attribute because those types always have a default value. You should make it a nullable integer instead. Same remark stands for the DurationUnit property if DurationUnit is an enum.

Problems converting an entity property to HiddenField in MVC

I have a Supplier Entitiy that contains
ID - int
Status - string
Name - string
CreateDate- datetime
I am using the partial class method to create Data Annotations for the above Entity.as described here
[MetadataType(typeof(SupplierMetadata))]
public partial class Supplier
{
// Note this class has nothing in it. It's just here to add the class-level attribute.
}
public class SupplierMetadata
{
// Name the field the same as EF named the property - "FirstName" for example.
// Also, the type needs to match. Basically just redeclare it.
// Note that this is a field. I think it can be a property too, but fields definitely should work.
[HiddenInput]
public Int32 ID;
[Required]
[UIHint("StatusList")]
[Display(Name = "Status")]
public string Status;
[Required]
[Display(Name = "Supplier Name")]
public string Name;
}
the HiddenInput annotation throws an error saying "Attribute 'HiddenInput' is not valid on this declaration type. It is only valid on 'class, property, indexer' declarations."
Please help
The error states that that attribute can only be added to 'class, property, or indexer declarations'.
public Int32 ID; is none of these - it is a field.
If you change it to a property
public Int32 ID { get; set; } you will be able to decorate it with that attribute.
All of your properties are defined incorrectly as they are missing the get/set accessors. All properties in .NET require getter and/or setter accessors. Change your code to this:
public class SupplierMetadata
{
[HiddenInput]
public Int32 ID { get; set; }
[Required]
[UIHint("StatusList")]
[Display(Name = "Status")]
public string Status { get; set; }
[Required]
[Display(Name = "Supplier Name")]
public string Name { get; set; }
}

ASP.NET MVC3 Conditional Validation of nested model for EditorTemplate

Suppose you have a viewModel:
public class CreatePersonViewModel
{
[Required]
public bool HasDeliveryAddress {get;set;}
// Should only be validated when HasDeliveryAddress is true
[RequiredIf("HasDeliveryAddress", true)]
public Address Address { get; set; }
}
And the model Address will look like this:
public class Address : IValidatableObject
{
[Required]
public string City { get; set; }
[Required]
public string HouseNr { get; set; }
[Required]
public string CountryCode { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
[Required]
public string ZipCode { get; set; }
[Required]
public string Street { get; set; }
#region IValidatableObject Members
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
string[] requiredFields;
var results = new List<ValidationResult>();
// some custom validations here (I removed them to keep it simple)
return results;
}
#endregion
}
Some would suggest to create a viewmodel for Address and add some custom logic there but I need an instance of Address to pass to my EditorTemplate for Address.
The main problem here is that the validation of Address is done before the validation of my PersonViewModel so I can't prevent it.
Note: the RequiredIfAttribute is a custom attribute which does just what I want for simple types.
Would have been a piece of cake if you had used FluentValidation.NET instead of DataAnnotations or IValidatableObject which limit the validation power quite in complex scenarios:
public class CreatePersonViewModelValidator : AbstractValidator<CreatePersonViewModel>
{
public CreatePersonViewModelValidator()
{
RuleFor(x => x.Address)
.SetValidator(new AddressValidator())
.When(x => x.HasDeliveryAddress);
}
}
Simon Ince has an alpha release of Mvc.ValidationToolkit which seems to be able to do what you want.
Update
As I understand it, the 'problem' lies in the DefaultModelBinder class, which validates your model on the basis that if it finds a validation attribute it asks it if the value is valid (quite reasonable really!), it has no notion of hierarchy. In order to support your required functionality you'll have to write a custom model binder that binds and then validates, if required, as determined by your declarative markup.
If you do write such a class it may be a good candidate for MVC futures.

Validation Attributes MVC 2 - checking one of two values

Could someone help me with this issue. I'm trying to figure out how to check two values on a form, one of the two items has to be filled in. How do I do a check to ensure one or both of the items have been entered?
I'm using viewmodels in ASP.NET MVC 2.
Here's a little snip of code:
The view:
Email: <%=Html.TextBoxFor(x => x.Email)%>
Telephone: <%=Html.TextBoxFor(x => x.TelephoneNumber)%>
The viewmodel:
[Email(ErrorMessage = "Please Enter a Valid Email Address")]
public string Email { get; set; }
[DisplayName("Telephone Number")]
public string TelephoneNumber { get; set; }
I want either of these details to be provided.
Thanks for any pointers.
You can probably do this in much the same way as the PropertiesMustMatch attribute that comes as part of the File->New->ASP.NET MVC 2 Web Application.
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public sealed class EitherOrAttribute : ValidationAttribute
{
private const string _defaultErrorMessage = "Either '{0}' or '{1}' must have a value.";
private readonly object _typeId = new object();
public EitherOrAttribute(string primaryProperty, string secondaryProperty)
: base(_defaultErrorMessage)
{
PrimaryProperty = primaryProperty;
SecondaryProperty = secondaryProperty;
}
public string PrimaryProperty { get; private set; }
public string SecondaryProperty { get; private set; }
public override object TypeId
{
get
{
return _typeId;
}
}
public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString,
PrimaryProperty, SecondaryProperty);
}
public override bool IsValid(object value)
{
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value);
object primaryValue = properties.Find(PrimaryProperty, true /* ignoreCase */).GetValue(value);
object secondaryValue = properties.Find(SecondaryProperty, true /* ignoreCase */).GetValue(value);
return primaryValue != null || secondaryValue != null;
}
}
The key part of this function is the IsValid function that determines if one of the two parameters has a value.
Unlike normal Property-based attributes, this is applied to the class level and can be used like so:
[EitherOr("Email", "TelephoneNumber")]
public class ExampleViewModel
{
[Email(ErrorMessage = "Please Enter a Valid Email Address")]
public string Email { get; set; }
[DisplayName("Telephone Number")]
public string TelephoneNumber { get; set; }
}
You should be able to add as many as these as you need per form, but if you want to force them to enter a value into one of more than two boxes (Email, Telephone or Fax for example), then you would probably be best changing the input to be more an array of values and parse it that way.

Resources