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.
精彩评论