I have a model like this:
public class Person
{
public int ID { get; set; }
[Required(ErrorMessage="Name cant be empty")]
public string Name { get; set; }
public Person Friend { get; set; }
}
I want to create a new Person, and made a form with the fields using the strongly typed HtmlHelper
- ID
- Name
- Friend ID (dropdown with options like
<option value="Friend.ID">Friend.Name</option>

When posting the form, my controller takes in a Person object (p), which is bound using the default modelbinder. Just to be explicit, the modelbinder does the following: The ID and Name properties are bound as expected. The Friend is set to a new Person instance whose ID equals the ID of the person I chose in the dropdown. The Friend.Name's value is null because I didn't provide a value for it in the form.
The problem: I want the RequiredAttribute to fire on the Name textbox if it is empty - and it does. The problem is that it also fires on the Friend's name attribute. So when I post, filling in all the fields, I get that the ModelState is invalid and the error being that p.Friend.Name is required.

How would I solve this problem? Of couse in this case I don't want to validate the Friend's properties. I've thought of:
- Using ViewModels for my views, which will somehow solve my problems. I haven't tried this yet as I feel I really shouldn't need to for such a simple problem
- Sending the friend's ID as a separate parameter,
friend_id, and binding theFriendproperty manually. Only theIDandNameattributes of the posted person is bound and I manually set theFriendproperty. This involves getting theFriendfrom my repository using thefriend_idto make it a "real" Person object. - Checking the ModelState and removing errors I know don't count. This is just plain wrong and non-scalable (have to remember to do this if I add for example a
SecondFriendproperty
I feel option 2 is the most feasable, but ideally I'd like it to be automatic. In addition, I can't use the strongly typed helper, as the friend_id textbox' name attribute must match the action method's parameter name.
I feel there's some point I've missed that would make this easier. Hopefully I'm right. Although I think it's a bit tedious using a ViewModel, it that's the correct thing to do, please do tell.
Edit
For now solved the problem using ViewModels with ID, Name and Friend_id as its properties and the same validation attributes as the Person model. I then map the ID and Name values over to a new Person instance. The Friend property is then set by loadning the specified friend from the repository. Like newPerson.Friend = repository.Get(viewModel.Friend_id)
When I get the time I plan on looking closer at AutoMapper to do this "automatically".