0

I have the following ViewModel (just showing few properties for easy reading)

public class Contract{

public string Name {get; set;}

public ContractTerm PrpTerm { get; set; }

}

the PRP Term model is something like this

public class PrpTerm{

public int Id {get; set;}
public string Name {get; set;}

}

For my model validations I'm using an XML file for injecting the annotations. I've set the Name property as required and I've let ContractTerm without specifying any validation (it's an optional field on a list). My view is something has a textbox for the Name and a select list for the Contract term.

When I'm trying to save, I get the ModelState.IsValid property as false, saying that the PRPTerm.Id value is required. I understand that it is since we cannot assing a null value to a int.

Does somebody know a way to avoid this to be validated?

I've tried using the Bind(Exclude annotation, but this removes the field from the data submission and this doesn't allow me to get the value the user selected (if that happened). I cannot set the id as nullable on the PrpClass. The other option is set the PrpTerm Id on the ViewModel but I need to justify that change with a valid reason.

Any idea?

2 Answers 2

9

An implicit [Required] attribute is applied to Id as it is an int which is, by definition, not-nullable (as opposed to int? which is nullable).

This behaviour is configurable in MVC using

DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes

which defaults to true.

You can disable this behaviour by setting it to false in your Global.asax.cs

However, as AFinkelstein points out, it sounds like the real issue is with your ViewModel. I would suggest you rethink that, rather than turning off this handy default of MVC.

I would suggest

public class Contract
{
    public string Name { get; set; }
    public int? PrpTermId { get; set; }
}

Is probably what you actually want. In terms of a 'valid reason' to do this - it is generally accepted that your ViewModels will often differ from your Models, as the purpose of a given ViewModel will likely be slightly different to that of the Models it is made up of.

Sign up to request clarification or add additional context in comments.

Comments

1

It doesn't sound like the PrpTerm class is appropriate for your View Model given you're not using its properties. All you really want is a PrpTermName set off of a drop down list. I would have a class structure like

public class Contract
{
    public string Name { get; set; }
    public string PrpTermName { get; set; }
    public SelectList ContractTermList { get; set; }
}

Now you don't need to worry about the validation of the ID because it's not part of your view model.

2 Comments

Actually, what I'm getting from the view is the selected id from that List. I understand that having the name or the id of that term on the view model will be the best option, but I cannot find yet an argument different than "The validation is not working" :(
The argument for not not including it is that a view model should only contain the properties and sub view models that you need. In this case, you're trying to bind a multiple property class using a dropdownlist, which by design lets you specify only one property. Including only one property in your ViewModel corresponding to the drop down list id you need makes the most sense. You can fetch the PrpTerm class (or domain class equivalent) in your controller, using this property after posting.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.