Home MVC, post partial model
Reply: 1

MVC, post partial model

JP Hellemons
JP Hellemons Published in 2017-11-12 19:51:50Z

This question already has an answer here:

  • Post an HTML Table to ADO.NET DataTable 2 answers

I have object A which has a List<ObjectB> ObjectB has several properties. Id, Mandatory, Name etc.

So I return a viewmodel (ObjectA) and have this in my razor:

@model ObjectA
<div>@Html.HiddenFor(m => ObjectA.ObjectC.ID)
    <dl class="dl-horizontal">
            @Html.DisplayNameFor(model => ObjectA.ObjectC.Name)

            @Html.DisplayFor(model => ObjectA.ObjectC.Name)
    // display stuff from objectA
    @using (Html.BeginForm())
        foreach (var ft in ObjectA.ObjectB)
            @Html.HiddenFor(c => ft.ID)
            <div class="row">
                <div class="col">
                @if (ft.Mandatory)
                    @Html.CheckBoxFor(c => ft.Mandatory, new { id = ft.ID, disabled = "disabled" })
                    @Html.HiddenFor(c => ft.Mandatory)
                    @Html.CheckBoxFor(c => ft.Mandatory, new { id = ft.ID })

and in my Controller I tried as input parameter: List<ObjectB> items but it was null. Now I know I could try FormCollection which I did and found out that form.Get("ft.id") had the amount of items in de objectB list. same for mandatory. But I'd like it strong typed. Either:

1 object A with all subobjects of type B

2 a list/ienumerable of type objectB.

It's probably a small thing, but I can't see it right now.

edit my model:

public class ObjectA : BaseViewModel
    public ObjectC DisplayOnly { get; internal set; }

    public List<ObjectB> Features { get; set; }

My view: (see above) My controller:

public ActionResult Details(ObjectA vm)
    if (ModelState.IsValid)
        int hid = Convert.ToInt32(RouteData.Values["id"]);
Shyju Reply to 2017-11-12 20:39:59Z

With your current code, it will render the checkbox input elements with name attribute values set to ft.Mandatory. When the form is submitted, model binder has no idea where to map this to because it does not match with the view model property names/property hierarchy. For model binding to work, the names of input should match with the parameter class's property name.

You can use Editor Templates to handle this use case.

Create a folder called EditorTemplates in ~/Views/Shared or ~/Views/YourControllerName and create a new view and give it the same name as your class name which you are using to represent the data needed for the checkbox. In your case it will be ObjectB.cshtml

Now make this view strongly typed to OptionB and render the checkbox and hidden input.

@model OptionB
    @Html.CheckBoxFor(x => x.Mandatory)
    @Html.HiddenFor(c => c.Id)

Remember, the browser will not send the values of disabled form elements when the form is submitted.

Now in your main view, you can call EditorFor helper method.

@using (Html.BeginForm())
    <button type="submit">Send form</button>

This will render the checkboxes with name attribute values like this (Assuming you have 3 items in OptionBList) , along with hidden inputs for checkboxes


Now you can simply use OptionA as the parameter of your HttpPost action method

public ActionResult Create(OptionA model)
   foreach(var item in model.OptionBList)
     //check item.Mandatory and item.Id
   //to do : return something
You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.398636 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO