1

Problem:

I am trying to take advantage of the AjaxExtension BeginForm in order to submit form data. The issue I am noticing is that complex objects in my model, and all of their properties, are being lost on the AJAX post due to the way MVC handles model binding. I can't seem to find a way of getting around this while keeping the separation I need between the various views. I did take a look at Passing two models to Controller using Ajax BeginForm() but the solution did not apply to my question, as the views were not split up into partials relying on different models.

This is what my code looks like (the essence of it, at least - changed names):

A.cshtml

@model A
<div>
    @using (Ajax.BeginForm("ActionA", "ControllerA", new { id = Model.Id }, new AjaxOptions { HttpMethod = "POST" }, new { id = "formId" }))
{
    @Html.Partial("ModelForm", Model.B)
}
</div>

B.cshtml

@model B
    ...
    <div>
        <p>@Html.TextBoxFor(x => x.Prop1)</p>
    </div>
    <div>
        @Html.EditorFor(x => x.ComplexObject1)
    </div>
    <div class="spacing">
        <p>@Html.TextBoxFor(x => x.Prop2)</p>
    </div>
    <div class="spacing">
        @Html.EditorFor(x => x.ComplexObject2)
    </div>
    ...

A.cs

    ...
    public B B { get; set;}
    ...

ControllerA.cs

    ...
    public ActionResult ActionA(A model) {
      //do something with model
    }
    ...

When I put a breakpoint in the ActionResult in the controller, the model object is instantiated, but the B property is null. If I add an @Html.HiddenFor(x => x.B.Prop1) and run the same code, I see that B is not null, but the property I did assign for Prop1 is lost. Also, if I add Prop1 to A.cs and run the same code, I notice that what I expected as B's Prop1 is assigned to A's Prop1 (this helped me understand how the binding was working). I basically want the form to recognize that within B.cshtml, all of the Html helpers are filling out the B object, which is a property in the A object, which gets sent to my controller. Is this possible?

2
  • You either need to pass the parent model to the partial @Html.Partial("ModelForm", Model) or specify the HtmlFieldPrefix as per this answer so the controls are correctly named. Commented Mar 3, 2015 at 21:43
  • This did the trick, thank you! It doesn't look like I can mark your comment as an answer to my question though. Commented Mar 3, 2015 at 22:07

2 Answers 2

1

It looks like the HtmlFieldPrefix, as pointed out by Stephen Muecke, is the solution to this problem.

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

Comments

0

Your model A having reference property for model B. So you can easily use properties from model B into the view that has binding with model A. You can try like this:

@model A
<div>
    @using (Ajax.BeginForm("ActionA", "ControllerA", new { id = Model.Id }, new   AjaxOptions { HttpMethod = "POST" }, new { id = "formId" }))
    {
      // @Html.Partial("ModelForm", Model.B)
         <div>
              <p>@Html.TextBoxFor(x => x.B.Prop1)</p>
         </div>
         <div>
               @Html.EditorFor(x => x.B.ComplexObject1)
         </div>
         <div class="spacing">
               <p>@Html.TextBoxFor(x => x.B.Prop2)</p>
         </div>
         <div class="spacing">
               @Html.EditorFor(x => x.B.ComplexObject2)
         </div>
    }
</div>

Thanks!

Comments

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.