58

This is the model with it's validation:

[MetadataType(typeof(TagValidation))]
public partial class Tag
{
}

public class TagValidation
{
        [Editable(false)]
        [HiddenInput(DisplayValue = false)]
        public int TagId { get; set; }

        [Required]
        [StringLength(20)]
        [DataType(DataType.Text)]
        public string Name { get; set; }
    //...
}

Here is the view:

    <h2>Create</h2>

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Tag</legend>

        <div>@Html.EditorForModel()</div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

And here is what get's renderd:

<form action="/Tag/Create" method="post">
    <fieldset>
        <legend>Tag</legend>
        <div><input data-val="true" data-val-number="The field TagId must be a number." data-val-required="The TagId field is required." id="TagId" name="TagId" type="hidden" value="" />

        <div class="editor-label"><label for="Name">Name</label></div>
        <div class="editor-field"><input class="text-box single-line" data-val="true" data-val-length="The field Name must be a string with a maximum length of 20." data-val-length-max="20" data-val-required="The Name field is required." id="Name" name="Name" type="text" value="" /> <span class="field-validation-valid" data-valmsg-for="Name" data-valmsg-replace="true"></span></div>            
    ...
    </fieldset>
</form>

The problem is that TagId validation gets generated althoug thare is no Required attribute set on TagId property. Because of that I can't even pass the client-side validation in order to create new Tag in db. What am I missing?

frennky
  • 12,581
  • 10
  • 47
  • 63

8 Answers8

103

I found the answer. Just add this to Application_Start:

DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
frennky
  • 12,581
  • 10
  • 47
  • 63
  • Thanks. Saved my day too. In my opinion this is backwards behavior. False should be the default. – Anish Dec 29 '11 at 16:16
  • 1
    @frnnky I added this but it didnt solve [link](http://stackoverflow.com/questions/14452344/remove-required-property) My prblem. will you please help me. Thank you – Amol Jan 22 '13 at 06:31
  • saved my day too!!! even without adding this, fluent validation could not work correctly!! – Khairul Islam Aug 20 '17 at 20:32
  • Is there any way to change what `RequiredAttribute` is implicitly used, rather than simply disabling this feature? – Sinjai Feb 14 '18 at 07:52
  • sweet jesus, how is this setting not the default. wasted an hour on this – Alan Waage Mar 29 '19 at 21:18
  • unfortunately, it's been removed in asp.net core :( – Miro Oct 02 '19 at 08:48
24

Make the view-model value-types nullable. Then they won't be Required by default.

Note also if you put the attribute 'required="false"' in html 5 (if you set html 5 in your doctype meta data), it will see "required" and make it required. You can use dojo-data-props="required:false".

Curtis Yallop
  • 6,696
  • 3
  • 46
  • 36
  • 2
    Why the downvote? Making the property nullable is a valid way to tackle this issue without having to make system-wide changes in Application_Start. – StuartQ Jul 23 '13 at 13:42
  • 2
    @StuartQ I agree with you so I up voted it to remove the down vote. Making the property nullable is a valid way to tackle this issue. It worked for me. – Ben Junior Apr 20 '14 at 22:41
  • Definitely the better answer! I'd rather not make system wide changes to tackle one problem in one view. Cheers – Johny Sep 06 '16 at 16:08
8

frennky's solution only removed data-val-required but in my case I still had data-val-number and data-val

I had to add the two lines below to Application_Start to get rid of everything.

ModelValidatorProviders.Providers.Clear();
ModelValidatorProviders.Providers.Add(new DataAnnotationsModelValidatorProvider());
nthpixel
  • 3,041
  • 3
  • 30
  • 42
  • 1
    @nuander valid concern. This is like using a sledgehammer to crack a nut. – user247702 Jun 28 '13 at 08:52
  • got an easier answer that worked for me here http://stackoverflow.com/questions/14452344/mvc3-removed-required-but-keeps-getting-data-val-required-attribute – TechnicalSmile Sep 13 '13 at 11:36
3

The problem is that the value of the hidden field is empty. This shouldn't happen if you use integer type. I suppose that the TagId property is defined as a nullable type in the Tag class. So either assign it a value before rendering the view or use an integer type:

[MetadataType(typeof(TagValidation))]
public partial class Tag
{
    public int TagId { get; set; }
    public string Name { get; set; }
}

so that the generated hidden field looks like this:

<input 
    data-val="true" 
    data-val-number="The field TagId must be a number." 
    data-val-required="The TagId field is required." 
    id="TagId" 
    name="TagId" 
    type="hidden" 
    value="0" 
/>

Also normally client side validation shouldn't be triggered for this hidden field.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • First, TagId isn't nullable, it's just int. Second, markup is generated by html helper EditorForModel so I don't have control over it. To set value to 0 I suppose I could send an empty instance of Tag to Create page, but that isn't the solution I'm looking for. – frennky Jan 16 '11 at 19:52
3

jquery validate target cheking "disabled" html attribute.

$(function () { 
  $("#TagId").attr("disabled", "disabled") 
});

or use Nullable.

hope this code!

takepara
  • 10,413
  • 3
  • 34
  • 31
2

With MVC4 you can also use this:

@{ Html.EnableClientValidation(false); }
@Html.EditorForModel()
@{ Html.EnableClientValidation(true); }
t2t
  • 1,101
  • 2
  • 12
  • 15
1

I had the unfortunate experience that my model attributes were suddenly required causing my web APIs to return 400 errors when attributes were missing from web requests.

I found out this was caused by an accidental change of the "Nullable" setting in the project (Project properties -> Build -> Nullable: Enable"

After changing Nullable to Disable, all was good again.

I found a more detailed explanation of the issue here:

https://learn.microsoft.com/en-us/dotnet/csharp/nullable-references#nullable-contexts

WeekendHacker
  • 196
  • 1
  • 6
0

Make your Model or View-Model property value-types "nullabel". This will solve your problem.One important thing that remove "required" attribute from your tag otherwise it will take i "required"

Example:-

public class ViewModle
{
    public int? foo{get;set;}
}

Here in example foo is integer nullable type, this will no longer required in mvc.

Hope this will help you.

Jani Devang
  • 1,099
  • 12
  • 20