Note that there are some explanatory texts on larger screens.

plurals
  1. POMVC 3 Model Validation Issue - Oversight or By Design
    primarykey
    data
    text
    <p><strong>I ran into a scenario where I needed to know which property was currently being validated</strong> in a custom <code>ValidationAttribute</code>. I assumed this would be easy in MVC 3 since the <code>ValidationContext</code> is being passed into the <a href="http://msdn.microsoft.com/en-us/library/dd730022%28v=VS.100%29.aspx" rel="noreferrer"><code>IsValid</code></a> method.</p> <p>Without going into detail, here is the basic idea:</p> <pre><code>protected override ValidationResult IsValid(Object value, ValidationContext validationContext) { if (ShouldICareAboutYou(validationContext.MemberName)) { //Do some stuff } //Return the results } </code></pre> <p>This seemed like the perfect solution, and indeed, when unit testing my custom ValidationAttribute using <a href="http://msdn.microsoft.com/en-us/library/dd411772%28v=vs.95%29.aspx" rel="noreferrer"><code>Validator.TryValidateObject</code></a> everything worked beautifully!</p> <p><strong>HOWEVER...</strong> </p> <p>When calling <a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.controller.tryupdatemodel.aspx" rel="noreferrer"><code>TryUpdateModel</code></a>, or <a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.controller.tryvalidatemodel.aspx" rel="noreferrer"><code>TryValidateModel</code></a> within my controller, the validation runs, but <code>ValidationContext.MemberName</code> is null.</p> <p><strong>Whaa Huh?!?</strong></p> <p>I did a little investigation and sure enough, right there inside of <a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.dataannotationsmodelvalidator.aspx" rel="noreferrer"><code>DataAnnotationsModelValidator</code></a> is the code... or lack thereof.</p> <pre><code>public override IEnumerable&lt;ModelValidationResult&gt; Validate(object container) { // Per the WCF RIA Services team, instance can never be null (if you have // no parent, you pass yourself for the "instance" parameter). ValidationContext context = new ValidationContext(container ?? Metadata.Model, null, null); context.DisplayName = Metadata.GetDisplayName(); // Setting the MemberName here would be trivial! // However, philh told me not to. Something about // a guy named Josh who pushed him down on the playground // in middle school. //context.MemberName = Metadata.PropertyName; (Suck It, Josh!!!) ValidationResult result = Attribute.GetValidationResult(Metadata.Model, context); if (result != ValidationResult.Success) { yield return new ModelValidationResult { Message = result.ErrorMessage }; } } </code></pre> <p>I realize that <code>DisplayName</code> <em>could</em> be the property name if no <code>DisplayAttribute</code> has been applied to the property. Unfortunately I can't really deal in hypotheticals. I need to know <strong>exactly</strong> what the property name is. </p> <p><strong>So what is the deal? Is this by design or an honest oversight.</strong> If it is an oversight, then it would be awesome to get this fixed in MVC 4 :)</p> <h2>Disclaimer:</h2> <p>The <em>added</em> comments in the code sample above are meant to be funny. I do not know, nor have I ever met <a href="http://haacked.com/articles/AboutHaacked.aspx" rel="noreferrer">Phil Haack</a>. From what I can tell he seems like a really nice guy. And pushing him down in middle school would have made me a royal douche!</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload