1

I have a view containing multiple partial views bind to different models.

@model MyApp.ViewModels.ParentViewModel

@Html.Partial("_PartialView1", Model.PartialView1)
@Html.Partial("_PartialView2", Model.PartialView2)

Unobtrusive validation works, problem is, the models for the views have properties with the same name.

public class ClassA
{
   public int SomeProperty { get; set; }
}

public class ClassB
{
   public int SomeProperty { get; set; }
}

public class ParentViewModel
{
   public int ClassA PartialView1  { get; set; }
   public int ClassB PartialView2  { get; set; }
}

Since both properties have the same name, their html name attributes are the same too.

If ClassA.SomeProperty has an error, same error is shown in ClassB.SomeProperty. Is there a way to have proper validation without changing the property names?

elodez
  • 13
  • 3

2 Answers2

1

Do not use partials (which result in duplicate name attributes without the correct prefix, and which cannot be bound to you model when you submit the form).

The correct approach is to use an EditorTemplate. Rename _PartialView1.cshtml to ClassA.cshtml and move it to the /Views/Shared/EditorTemplates folder (ditto for _PartialView2 which needs to renamed to ClassB.cshtml - i.e. to match the name of the class). Then in the main view its

@model MyApp.ViewModels.ParentViewModel
....
@Html.EditorFor(m => m.PartialView1)
@Html.EditorFor(m => m.PartialView2)

Your html will now generate the correct name attributes

<input name="PartialView1.SomeProperty" .... />
<input name="PartialView2.SomeProperty" .... />

and the associated @Html.ValidationMessageFor() will also match up correctly

Side note: You can also solve this using a partial by passing the prefix as additional ViewData as per this answer, but the correct approach is to use an EditorTemplate

Community
  • 1
  • 1
  • Nice! thanks! I'll try this out at once. One question, is there a significant advantage of using editor templates over the prefixing way? – elodez Dec 05 '15 at 02:44
  • The `EditorFor()` method is designed for this and it means you do not have to pass magic strings (the prefix) to a partial (which make you code much harder to maintain - what if you later changed the name of the property?). Also the `EditorFor()` method accepts `IEnumerable` so if you have a property say `List myProperty` then `EditorFor(m => m.myProperty)` will generate the correct html including the necessary indexers for binding to the model. –  Dec 05 '15 at 02:50
0

Unless they are in separate forms I don't think it is possible without giving them a different name.

Hintham
  • 1,078
  • 10
  • 29