开发者

@Html.Partial in Ajax.BeginForm does not post data to action

When i try to post data and call a action from a view having partial view i do not get the Model data for the partial view but when i use it directly and not the partial view it sends the data prop开发者_JAVA技巧erly.

<div id="mydiv">
    @using (Ajax.BeginForm("Index1", "Home", new AjaxOptions { UpdateTargetId = "mydiv", InsertionMode = InsertionMode.Replace, HttpMethod = "Post" }))
    {        
        //Does not send data to action on post  
        @Html.Partial("ViewUserControl1",Model.Emps)
        //ViewUserControl1 contains the same next 8 line logic.
        OR

        //Send the data to actions on post.
        for (int i = 0; i < Model.Emps.Count(); i++)
        {
            @Html.TextBoxFor(x => x.Emps[i].Name)
            @Html.TextBoxFor(x => x.Emps[i].Address)
            @Html.ValidationMessageFor(x => x.Emps[i].BBString)
        <br />    
        }

        <input id="dosomething" type="submit" value="save" />
    }
</div>


///On Controller 
   [HttpPost]
   public ActionResult Index1(MyModel model)
   {
      ///Here i am looking for the model data which is null for partial.
      return View(model);
   }

Where MyModel has a List of Emps { Name,Address}

Does anybody know the reason for this.


I suspect that your ViewUserControl1 partial looks like this (you haven't shown it, you just said that it looks like the following 8 lines but it obviously it doesn't look those 8 lines because it uses a different view model):

@model IEnumerable<Employee>

for (int i = 0; i < Model.Count(); i++)
{
    @Html.TextBoxFor(x => x[i].Name)
    @Html.TextBoxFor(x => x[i].Address)
    @Html.ValidationMessageFor(x => x[i].BBString)
    <br />    
}

Notice the missing Emps property in the lambdas? This generates invalid names for the input fields and the default model binder does not fetch the values when you post back.

I would recommend you using editor templates instead of partial views, like this:

<div id="mydiv">
    @using (Ajax.BeginForm("Index1", "Home", new AjaxOptions { UpdateTargetId = "mydiv", InsertionMode = InsertionMode.Replace, HttpMethod = "Post" }))
    {        
        @Html.EditorFor(x => x.Emps)
        <input id="dosomething" type="submit" value="save" />
    }
</div>

and then inside ~/Views/SomeControllerName/EditorTemplates/Employee.cshtml simply:

@model Employee
@Html.TextBoxFor(x => x.Name)
@Html.TextBoxFor(x => x.Address)
@Html.ValidationMessageFor(x => x.BBString)
<br/>

The editor template will be rendered for each element of the Emps collection so that you do not need to write any loops. It will generate proper names for the input fields so that the default model binder is able to populate the values on postback. The editor template location is important. It must be placed either inside ~/Views/Shared/EditorTemplates (if you want it to be reused between multiple controllers) or inside ~/Views/SomeControllerName/EditorTemplates (if you want it to be reused only between the views of a given controller). The name of the template is also important. It should be called the same as the type of the collection. So for example if you have a property public IEnumerable<Employee> Emps { get; set; } in your view model, the template must be called Employee.cshtml so that it is automatically rendered for each element of this collection.


This is a good article i found while searching

http://lostechies.com/jimmybogard/2011/09/07/building-forms-for-deep-view-model-graphs-in-asp-net-mvc/

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜