简体   繁体   中英

Add dataAnnotation on demand to validate a form + mvc4

I need to validate a form, this is my model:

 public class Movie {
    public int ID { get; set; }

    [Required]
    public string Title { get; set; }

    [DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }

    [Required]
    public string Genre { get; set; }

    [Range(1, 100)]
    [DataType(DataType.Currency)]
    public decimal Price { get; set; }

    [StringLength(5)]
    public string Rating { get; set; }
}

My question is: I have a querystringParam that contain a cinemaId, when i read this param i read from database a configuration of each property is required or no. Sometimes I need to add [Required] to the property and sometimes No, How can i do this please??

You have to modify the ModelState in the controller actions.

In your post action, load the database configuration check each property, and add the errors to the ModelState property like this:

if (/* the property value is wrong */)
{
  ModelState.AddModelError("propertyName", "message");
}

These errors will be treated just as if they had been generated by MVC framework using the data annotations (adding styles to rendered controls, appearing in the list of errors and so on).

If the property is nested use dots, like this: "property.subproperty.subproperty" for the property name parameter.

Building up on the answer @JotaBe gave, you could use a custom validation attribute on the Model property itself. Something like this :

Conditional Required Attribute

public class ConditionalRequiredAttribute : ValidationAttribute
{
    private const string DefaultErrorMessageFormatString 
                   = "The {0} field is required.";

    private readonly string _dependentPropertyName;

    public ConditionalRequiredAttribute(string dependentPropertyName)
    {
        _dependentPropertyName = dependentPropertyName;
        ErrorMessage = DefaultErrorMessageFormatString;
    }

    protected override ValidationResult IsValid(
                object item, 
                ValidationContext validationContext)
    {
        var property = validationContext
                         .ObjectInstance.GetType()
                         .GetProperty(_dependentPropertyName);

        var dependentPropertyValue = 
                            property
                            .GetValue(validationContext.ObjectInstance, null);

        int value;
        if (dependentPropertyValue is bool 
                           && (bool)dependentPropertyValue)
        {
            /* Put the validations that you need here */
            if (item == null)
            {
              return new ValidationResult(
                  string.Format(ErrorMessageString, 
                                validationContext.DisplayName));
            }
        }

         return ValidationResult.Success;
    }
}

Applying the Attribute

Here I have a class Movie and the Rating is required depending on the value of RatingIsRequired boolean property which can be set from the server.

public class Movie
{
   public bool RatingIsRequired { get; set; }

   [ConditionallyRequired("RatingIsRequired"]   
   public string Rating { get; set; }
}
  1. With this the ModelState.IsValid will return false if RatingIsRequired set to true and Rating is empty.
  2. Also You can write a custom unobtrusive jquery validator to for client enabled validations so that is works like regular [Required] attribute.

Let me know if this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM