开发者

Multiple custom validation attributes on a class mvc

开发者 https://www.devze.com 2022-12-21 05:06 出处:网络
I am creating a example for better understanding. [CustomValidator(\"Property1\",\"Property2\", ErrorMessage= \"Error1\")]

I am creating a example for better understanding.

[CustomValidator("Property1","Property2", ErrorMessage= "Error1")]
[CustomValidator("Property3","Property4", ErrorMessage= "Error1")]
public class MyViewModel
{
    public string Property1 {get; set;}
    public string Property2 {get; set;}
    public string Property3 {get; set;}
    public string Property4 {get; set;}
}

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
public class CustomValidator : ValidationAttribute
{
    All the required stuff is written.
}

Only the second validator (or the last one in the list) gets fired and ignores the first one. I am not sure if this is th开发者_运维百科e right approach for this scenario. Any suggestions?


if you are using Linq to SQL why not try something like this

add a rule violations class to handle rule violations

public class RuleViolation
{
    public string ErrorMessage { get; private set; }
    public string PropertyName { get; private set; }
    public RuleViolation(string errorMessage)
    {
        ErrorMessage = errorMessage;
    }
    public RuleViolation(string errorMessage, string propertyName)
    {
        ErrorMessage = errorMessage;
        PropertyName = propertyName;
    }
}

now on your data class

[Bind(Exclude="ID")]
public partial class Something
{
    public bool IsValid
    {
        get { return (GetRuleViolations().Count() == 0); }
    }

    public IEnumerable<RuleViolation> GetRuleViolations()
    {
        if (String.IsNullOrEmpty(Name.Trim()))
            yield return new RuleViolation("Name Required", "Name");
        if (String.IsNullOrEmpty(LocationID.ToString().Trim()))
            yield return new RuleViolation("Location Required", "LocationID");
        yield break;
    }

    partial void OnValidate(ChangeAction action)
    {
        if (!IsValid)
            throw new ApplicationException("Rule violations prevent saving");
    }

}

and in your controller's methods for updating, use the updatemodel method for changing properties

Something something = somethingRepo.GetSomething(id);
try
{
    //update something
    UpdateModel(something);
    somethingRepo.Save();
    return RedirectToAction("Index");
}
catch
{
    ModelState.AddRuleViolations(something.GetRuleViolations());
    return View(something);
}

this way you can just add rules to your data class as it changes and it will be reflected in your updates, etc


I found another question that answers this. You have to override Attribute.TypeId.

Custom validation attribute with multiple instances problem


you dont really need all that code use data annotations by creating a metaData class for your model link text

that should set you on the right road also read up on html helpers and buddy classes ( this is what they call em)


I had the same problem.

I come up with the following solution.

Your POCO class might implement interface IValidatableObject.

This requires from you to implement the following method.

    public virtual IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        // return list of appropriate ValidationResult object            
        var customResult = new List<ValidationResult>();
        customResult.Add(new ValidationResult("message", new List<string>(){"Property1"});
    }

You can place any validation logic there. This has also the advantage over class-level attribute. Class-level attribute can only be shown in ValidationSummary (they are not related to any property). In contrast to it you can set specific members while returning ValidationResult. This allows to show validation information beside specific control to which the message concerns.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号