Gray's Matter
Justice Gray - North America's Favorite Metrosexual Urban Legend
   by Justice~! Technical  

Microsoft MVC 2 - Steaks and stones and the failure of the required attribute

"I can't see the difference, can you see the difference?"

I say to my wife and 4 of her friends, "I will grill steaks for tonight's dinner.  They will be on the table at 6 PM".

At 6 PM, we all sit down to the table and I place a rock on each plate, said rock still being slightly damp as I scooped them out from the harbor 20 mins before.

My wife complains, "I thought you were grilling steaks?"
One friend says, "This isn't like any steak I've ever seen"
Another one says, "Not only is this not steak, but it can't be grilled.  It is wet!!"

I reply to them, "Ha!!  Grilling steaks doesn't mean what you think it does!!"

So, in conclusion is this situation:
a) the fault of my friends, who should have asked me what I meant by "grilling steak"
or
b) my fault for communicating something completely different from the commonly held expectation of every human being on the planet?

Comments

Haacked

One bad analogy deserves another. Tong

I was out with my friends last night and we walked up to the door of a bar. The bouncer tells us that "Payment is REQUIRED". We decide not to enter and turn to leave and the bouncer grabs me by the collar and says, "Hey, didn't you see the sign? Payment is required". I replied, "But I didn't even try to enter".  He says, "What part of the commonly held expectation of the definition of Required that every human being on the planet understands didn't you understand?"

Apparently the part where we define exactly *what context* is the thing required.

I think this is the situation that Brad describes in his post. The context we assumed that Required applied to is the context of attempting to set a value. If you don't even attempt to set it, then it's not required. Much like if you don't attempt to enter the bar, payment isn't required.

Of course in the specific case of the RequiredAttribute, based on feedback, it sounds like most people understand it to mean it is required whether or not you try to set the value. If that's the expectation most people have, then we made a misjudgment and will look at fixing it to meet expectations.

My point in making the counter-analogy is to point out that when you frame a design decision like this, you can make any decision sound stupid. But in light of other contexts, it can also sound reasonable, but perhaps misguided.

I'm not saying I disagree with you though, in retrospect, it does sound like the context we had in mind doesn't meet most people's expectations of how it works.

Reply

#2 Rob Conery United States on 1/21/2010 9:18:48 PM

Rob Conery

>>> If you don't even attempt to set it, then it's not required. Much like if you don't attempt to enter the bar, payment isn't required

So much wrong with this. Love you man, but dude you're reaching and it's silly.

First - "if you don't even attempt to set it". Who cares what I attempted? It's required - THROW.

Second - in your analogy - the payment is still required. You left the bar so it nullifies the situation - but payment *is still required* at the bar. The bouncer didn't look at you and say "oh - you don't want to pay? Well OK come on in!".  

It's pretty straightforward (technically): Required isn't. It's triple-clear on a business front: Rails does it this way Smile.

Reply

Steven Harman

@rob, very true, sir! but then, this is the difference between how Rails has been build (by extracting from and building on real-world use) vs. how asp.net mvc has been build (lots of off in the weeds speculation about how folks might/ought to use it).

@phil... still loves ya homie, but... what rob said.

Reply

Steven Harman

damn typos! clearly i meant "built," not "build." weak in the ways of the grammar, have I grown...

Reply

Chris Nicola

Arguably, if you don't pass model data to the view that the view doesn't use this issue becomes mute, in other words using a ViewModel that is properly matched to that View.

Reply

Haacked

@Chris, yes, that's exactly true. The crux of the issue is whether people think partial editing is important or not.

@Rob silly!? C'mon man, you're so intent on making your point you don't care to understand mine. Tong

1. I agree with you. The current behavior needs to be fixed. We listened. We're going to fix it.
2. I'm trying to explain that the fix for the current behavior itself will bite people too.

I'm not justifying the original decision, I'm only saying that it too is based on real world scenarios that people have reported and isn't as unreasonable as you make it out to be. Why would I even bother? Because I think it's important to understand the implications of this change to your code moving forward.

If you re-use models for multiple controller actions, this change will affect you. In fact, Rob, I looked through your MVC Storefront and you generally follow this pattern of using the same model for different actions. You don't create view models specific to each action method.

What's the issue? Suppose you have a User class with a Confirmed property.

  public class User {
    public bool Confirmed {get; set;}

    // ... other properties
    [Required]
    public string UserName {get; set;}
  }

You build an admin screen that just allows you to mark a user as confirmed which posts to the following action method:

  public ActionResult ConfirmUser(User user) {
    //...
  }

The form only has one form field on it, Confirmed. However everytime you post to this action method, you get validation errors. WTF?! Oh yeah, we validate all properties now, not just the ones you meant to edit.

With this change, you really ought to create a view model specific to each action as Chris mentions (which I think is good practice anyways).

Reply

John Petersen

Hi Phil...

For the most part I agree with you...develop a model specific each action - if warranted. That still does not mean that model validation should be dependent on what is/is not in the view. If I specify in the model (any model) that a field is required, then anything that operates against that model has to subject to that rule. You should not have a case where the rule does not get called because something is absent from the view.

Not to bring personalities into it  - I think the big rub here is the level to which Brad defended the current situation.

As always, I appreciate your thoughts and your candor.

JVP

Reply

John Petersen

I with Rob on this. I don't see how "context" is relevant here. Indeed, I can define a context that justifies and supports a technical argument or any other argument for that matter. If we agree what the basis of the MVC pattern is, that becomes the one and only relevant context. As Rob said, and as I illustrated on Brad's blog, Rails does this correctly. Ironically, I used the Nerd Dinner on Rails project to illustrate how Rails handles this situation correctly.

The bottom line is this - we write business rules against models. The model and its rules defines what is/is not valid. Accordingly, the model must be the arbiter of what is/is not valid. A view is simply an interface to a model. To validations against a view and not the model is to not validate at all.

Reply

Chris Nicola

If there is anything being a developer has taught me is that context is *always* relevant (even if we are talking about non-developer things).

That said, I do agree that on the flip side multitudes of people reporting the same issue may be an indication that the context is as clear as mud... may be.  Or it may just be that there are still many people in the .NET space who don't fully understand the MVC context yet.

Personally I have to agree here, if I don't have a property in my View then I don't intend for that view to validate it, even if I am being a lazy coder and just passing my domain entities all over the place for people to look at and edit directly.

Domain model validation should happen in the domain, user input validation should happen in the view/controller, but I believe they should be kept separate.

Reply

John Petersen

I wasn't saying context is never relevant. What I am saying is that as far as this specific issue is concerned, context is a known constant because the context is already defined, the context being the way MVC works - or is supposed to work. Unless of course, that is up for debate...And - we are talking about the plain meaning of words here. Anything else where you have to start maneuvering around those definitions, you have added necessary complexity, complexity that does not yield value.

All that said,  I do agree that context matters.

Reply

Add comment

If you're going to leave a comment, please use your real name rather than a business name; otherwise it'll likely get blocked by my spam filter (or in the rare case it gets through, deleted by me manually). Thanks!


(will not be published)

  Country flag

Click to change captcha
biuquote
  • Comment
  • Preview
Loading