James
James

Reputation: 45

POSTing ViewModel contained in other ViewModel asp.net mvc

I have a ViewModel which contains two other ViewModels (stripped for brevity):

class SmallViewModel1
{
    public string Item { get; set; }
}

class SmallViewModel2
{
    public string Item { get; set;}
}

class BigViewModel {
    public SmallViewModel1 Model1 { get; set; }
    public SmallViewModel2 Model2 { get; set; }
}

I then have a View which accepts BigViewModel as its model. The view has two forms which POST to two different actions.

@model BigViewModel

@using (Html.BeginForm("Action1","Controller",FormMethod.Post))
{
    @Html.TextBoxFor(t=>t.Model1.Item)
}

@using (Html.BeginForm("Action2","Controller",FormMethod.Post))
{
    @Html.TextBoxFor(t=>t.Model2.Item)
}

Then in the controller I am trying to do something like this:

public ActionResult Action1(SmallViewModel1 model)
{
    ....
}

public ActionResult Action2(SmallViewModel2 model)
{
    ....
}

The issue I am running into is if I use the 'For' controls (EditorFor, TextBoxFor, etc) my POSTed model is null. I think this is because it expects me to POST the full ViewModel (BigViewModel) and it names the inputs expecting this: <input name="Model1.Item". To get around this I have been using the non 'For' control and just setting the name to the SmallViewModel's property, for example: @Html.TextBox("Item"). This maps correctly to the controller and everything ends up working.

My questions is am I doing this correctly? I've been googling around for a bit and haven't found anything but I feel like there is a better, or more 'best-practice' way to do this.

Upvotes: 0

Views: 65

Answers (1)

Hardik Gondalia
Hardik Gondalia

Reputation: 3717

Your Controller should be like this

public ActionResult Action1(BigViewModel model)
{
    ....
}

public ActionResult Action2(BigViewModel model)
{
    ....
}

As you have taken BigViewModel, When you submit it should have same model in parameter

Alternatively you can use the Prefix property of the BindAttribute

public ActionResult Action1([Bind(Prefix="Model1")]SmallViewModel1 model)
{
    ....
}

public ActionResult Action2([Bind(Prefix="Model2")]SmallViewModel2 model)
{
    ....
}

Upvotes: 2

Related Questions