Hooman Bahreini
Hooman Bahreini

Reputation: 15559

Determine model type in Ajax Post

I have an ASP.NET MVC View. In my View I want to make an AJAX Post request to update a PartialView inside the view.

This is my Model:

public class HomeListViewModel
{
    public MainQueryViewModel MainQuery { get; set; }

    // other properties
}

And this is my View (which has a PartialView):

@model MyNameSpace.HomeListViewModel

@using (Ajax.BeginForm("List", new AjaxOptions { UpdateTargetId = "browsePartialView", HttpMethod = "Post" }))
{
    @Html.AntiForgeryToken()
    <div id="browsePartialView">
        @Html.Partial("_MainQuery", Model.MainQuery)
    </div>
}

Now this is my problem: I want AJAX to POST an object of type: HomeListViewModel to the controller, but AJAX Posts an object of type MainQuery.

This is my Controller Action:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult List(HomeListViewModel HomeListViewModel)
{
    var myModel = HomeListViewModel;    // <-- an empty model is passed in

    // some action
}

If I change the param type to: MainQuery, then it works fine:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult List(MainQuery MainQuery)
{
    var myModel = MainQuery;    // <-- all ok

    // some action
}

Is there a way to tell AJAX what type of Model it should post to Controller?

Upvotes: 0

Views: 54

Answers (1)

user3559349
user3559349

Reputation:

Your use of Html.Partial() is generating form controls with name attributes that relate to MainQueryViewModel, not HomeListViewModel.

The preferred method is to use an EditorTemplate which will prefix the name attributes so that you get name="MainQuery.someProperty" instead of name="someProperty" which you currently get.

Change the name of your partial to MainQueryViewModel.cshtml (to match the name of the class) and move it the /Views/Shared/EditorTemplates (or /Views/yourControllerName/EditorTemplates) folder, and to generate the html use

@Html.EditorFor(m => m.MainQuery)

Another option for adding the prefix is to pass the prefix using additionalViewData

@Html.Partial("_MainQuery", Model.MainQuery, 
new ViewDataDictionary { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "MainQuery" }})

And for a HtmlHelper extension method that simplifies it to @Html.PartialFor(m => m.MainQuery, "_MainQuery"), refer getting the values from a nested complex object that is passed to a partial view.

Upvotes: 1

Related Questions