2

Using Data Annotations to specify validation rules for a model, I want to set the initial value for the Required attribute so that it fails if it's equal to that value. This was an option in webforms using the validation controls, but I don't see similar using Data Annotations.

If there's no built in way to do it, I'll probably just build a new Required Attribute that inherits from it.

UPDATE: Based on comments/answers, I definitely know this is not an ideal situation and I should be using the placeholder attribute of HTML5. However, I need to do this for an existing form that already had shadow text being added in a non-ideal way.

jwynveen
  • 1,261
  • 3
  • 15
  • 34

4 Answers4

2

I wouldn't handle that in MVC, I'd work on getting the shadow text to not post with the form. HTML 5 has "placeholder". I'd use that or implement something like it: http://davidwalsh.name/html5-placeholder

Check this out for a simple quick placeholder approach that degrades properly in non-html5 browsers:

JQuery placeholder HTML5 simulator

Just add the placeholder attribute to your textboxes and use that javascript to make it work regardless of HTML version.

Community
  • 1
  • 1
Milimetric
  • 13,411
  • 4
  • 44
  • 56
  • I would agree that the shadow text shouldn't be posted, but I think it would still be somewhat worthwhile to check server-side as well in case the javascript fails or some other client-side failure. – jwynveen Aug 01 '11 at 18:17
  • 1
    Well, but then you would be tightly coupling your model/controller code to an arbitrary string value that you're using in your view. It's kind of against the MVC paradigm – Milimetric Aug 01 '11 at 19:53
  • Agreed. Not a fan of doing this tight coupling, but just trying to get a fix done quickly. However, wouldn't it be a similar coupling as the Display(Name="xyz") attribute? Since the display name is used to build label that have the same purpose as shadow text, wouldn't it be similar? Especially if I would use the Display Name to create the shadow text and then pull the initial value of the RequiredAttribute from the DisplayName? Probably won't do this due to time constraints, but just thinking theoretically. – jwynveen Aug 01 '11 at 20:31
  • well, speaking from the MVC perspective, it's ok for the View to use information about the Model. So in this case the View would key off of the Model's Display attributes. However, if you pass that value back to the controller and make the controller have rules to filter it out, that's problematic. If someone is maintaining your code a year from now and they change the Display attribute's value, there's no convention that tells them to look at the Controller's Save Action to make sure they didn't break something. Basically, these conventions are there for maintainability's sake. – Milimetric Aug 01 '11 at 20:59
0

I dont know there is any built in annotations available or not for notequalto, but you can create your own NotEqualAttribute, inheritValidationAttribute (for validation on server) and implement IClientValidatable (to produce data-something tags, to do validation on client).

Also you have to write code in jquery for client validation.

refer this

How does DataAnnotations really work in MVC?

Community
  • 1
  • 1
Praveen Prasad
  • 31,561
  • 18
  • 73
  • 106
0

I ended up creating a new attribute that inherits from the RequiredAttribute:

public class RequiredWithInitialValueAttribute : RequiredAttribute
{
    public string InitialValue { get; set; }

    public RequiredWithInitialValueAttribute(string initialValue)
    {
        InitialValue = initialValue;
    }

    public override bool IsValid(object value)
    {
        if (value.ToString().SafeEquals(InitialValue)) return false;
        return base.IsValid(value);
    }
}

Still curious if there's a better way since this seems like something that should be built in, but for now I'm using this.

jwynveen
  • 1,261
  • 3
  • 15
  • 34
  • While I applaud your effort, this strategy is just plain wrong. Placeholder is *purely* a view thing, it has *nothing* to do with the model or validation. Think of it as of an overlay and not a real “value” at all. – Dan Abramov Aug 01 '11 at 21:30
  • What will you do when you need a *number-only* field with a string placeholder? You'd need to be careful about your initial value being validated.. What about the time you need to localize your app? – Dan Abramov Aug 01 '11 at 21:34
  • 1
    The place I'm using this is a short-lived form that will never be localized. I just needed a quick way to do this based on how my front-end developer built out the HTML. In the future, placeholder will likely be used. This is by far not a long term or permanent solution. It's just fixing an existing form (that was built in a non-ideal way) that was posting the placeholder text. – jwynveen Aug 03 '11 at 13:37
0

Don't do this.

Placeholder text is not a value. It should not be posted. It should not be validated.
This contradicts common sense, is a crime against humanity and introduces several problems.

  • What if you need an optional number field with a placeholder text?
    (Validation will fail because placeholder is a string.)

  • What happens when your application is localized?
    (Validation will fail until someone finds this attribute value is being compared with.)

  • Validation will have to be server-only and there will be no way to “grey out” placeholder text.
    (Unless you specify the placeholder once more in the script file and monitor change events.)

  • You will have to specify this “placeholder” at least twice, and in different places.
    (If I got you right, it's once in the attribute and once in the constructor.)

  • There will be no way for placeholder to actually be the value.
    (This can happen, if not for this field, then for any other that uses the attribute.)

  • This will freak the hell out of the future maintainers.
    (Do you even doubt that?)

Instead,

Use placeholder attribute and degrading solutions as suggested by Milimetric.

As an alternative for restless DYI-ers, place the label in a div and position it over the input field with your own JavaScript. This is known as “overlabel” technique and there are plenty examples on the web. (But you'll have to test your solution thoroughly on the browsers you want to support.) You may even roll out your own custom HTML helper:

@Html.PlaceholderFor(m => m.SomeField)

(I completely made it up, it's up to you to implement it.)

Community
  • 1
  • 1
Dan Abramov
  • 264,556
  • 84
  • 409
  • 511