Partial View not posting selected values back

Ok I pass a viewmodel to the page inside the view model consist of three classes and a class called Filter.

I have three views each have a table on but all require the same search functionality, so i decided to put the filter in a partial view.

below is how one of my controller look.

 [HttpGet]
        public ActionResult Hierarchy()
        {
            var vm = new ProjectViewModel();

            try
            {
                var userId = (int)WebSecurity.CurrentUserId;
                var isAdmin = User.IsInRole("Admin");

                vm = new ProjectViewModel
                {
                    Filter = new FilterResults(),
                    DealerHierarchy = new DealerHierarchy().GetPosition(null, null, userId, isAdmin)
                };

                vm.Filter.PaymmentStatus = new PaymentStatus().ReturnStatus(); // Build the selected Status
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
            return View(vm);
        }

vm.Filter is the search i.e fromDate toDate etc

below is how my view is contructed, you can see I pass down the Filter from the vm into the Partial View.

<h2>Hierarchy</h2>

@using (Html.BeginForm("Hierarchy", "Dealer", FormMethod.Post))
{
    @Html.Partial("~/Views/Shared/Filter.cshtml", @Model.Filter)
    <p>
        <button type="submit">Filter</button>
    </p>
}
<table>
    <thead>
        <tr>
            <th>Dealer Name</th>
            <th>Commission Amount</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.DealerHierarchy)
        {
            <tr>
                <td>
                    @item.DealerName
                </td>
                <td>
                    @String.Format("{0:n0}", item.CommissionAmount)
                </td>
            </tr>
        }
    </tbody>
</table>

This is the partial view

@model SomeApp.Models.FilterResults

<style type="text/css">
    .filter-container {
        width: 500px;
        margin-left: auto;
        margin-right: auto;
    }
</style>

<div class="filter-container">
  
    @Html.TextBoxFor(m => m.FromDate, new { @placeholder = "From Date", @Id = "txtFromDate" })

    @Html.TextBoxFor(m => m.ToDate, new { @placeholder = "To Date", @id = "txtToDate" })

    @Html.DropDownListFor(m => m.SelectedPaymentStatus, Model.PaymmentStatus, new { @ID = "drpPaymentStatus" })
</div>

All renders correct, but when I press Filter on the actual view it posts back but the values I have entered into the partial view aren’t passed back….

Any help?

Harrison.Scott

@using (Html.BeginForm("Hierarchy", "Dealer", FormMethod.Post))

Your filter form posts to the Hierarchy action inside the Dealer controller

Harrison.Scott

[HttpGet]
        public ActionResult Hierarchy()

But this action is defined as HttpGet. You need another Hierarchy action which accepts a post.

First of all this:

@Html.Partial("~/Views/Shared/Filter.cshtml", @Model.Filter) // @ is not needed here for before Model

should be like this:

@Html.Partial("~/Views/Shared/Filter.cshtml", Model.Filter)

You need a post action as well which will task your partial view model as parameter:

[HttpPost]
public ActionResult Hierarchy(SomeApp.Models.FilterResults model)
{

 // do something here with model posted

}
Sorry I already have a post action for the page, the controller snippet I showed above was where it was loading and populating the filter class inside the view model.

My post method expects the view model but yet filter values are null

can you show your that action here??

Harrison.Scott

My post method expects the view model but yet filter values are null

Your post method should expect ProjectViewModel as the input parameter. As Model binding is done by naming convention, your input model should be same as that of the parameters that is passed.

Best way is to view the generated html and from there determine the object that will be passed. Please post your generated html for the form.

binding counts on the name of the fields to be correct. to bind your partial view fields, they need to have the Filter. prefix (Filter.FromDate). your partial view does not know about the  prefix set so its rending the wrong field names. use:

 @Html.Partial("~/Views/Shared/Filter.cshtml") 

and use the complete model name (m=>m.Filter.FromDate) in the partial.

note: if you google you can find sample code to build a partial view that supports passing a prefix.

also if you want the partial reusable, define an IFilter interface that is just the property Filter of type FilterResults. then you can have multiple model implement the interface, and use the interface as the model type in the partial.   

Hi Bruce,

My view now looks like this

@using (Html.BeginForm("Hierarchy", "Dealer", FormMethod.Post))
{
    @Html.Partial("~/Views/Shared/Filter.cshtml", Model)
    <p>
        <button type="submit" value="Filter"></button>
    </p>
}

I have changed my partial view so it now looks like this

@model SomeApplication.ViewModel.ProjectViewModel

    <style type="text/css">
        .filter-container {
            width: 500px;
            margin-left: auto;
            margin-right: auto;
        }
    </style>

    <div class="filter-container">

        @Html.TextBoxFor(m => m.Filter.FromDate, new { @placeholder = "From Date", @Id = "txtFromDate" })

        @Html.TextBoxFor(m => m.Filter.ToDate, new { @placeholder = "To Date", @id = "txtToDate" })

        @Html.DropDownListFor(m => m.Filter.SelectedPaymentStatus, Model.Filter.PaymmentStatus, new { @ID = "drpPaymentStatus" })
    </div>

my controller

 [HttpPost]
        public ActionResult Hierarchy(ProjectViewModel vm)
        {

            DateTime? fromDate = vm.Filter.FromDate;

            return View(vm);
        }

yet my values are still null unless I have missed something?

Leave a Reply