Search code examples
c#asp.net-mvc-5asp.net-mvc-viewmodel

How to post objects in ViewModel?


I've got this viewmodel class with an integer Id and an object type.

public class MyViewModel
{
    [Required]
    public int MyId { get; set; }

    public MyObject MyObject { get; set; }
}

MyObject Model is:

public class MyObject 
{
    [Key]
    public int ObjId { get; set; }

    public int Number { get; set; }
    public string Name { get; set; }

}

This controller:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "MyId, MyObject.Number, MyObject.Name")]MyViewModel vm)
{
    if (!ModelState.IsValid)
    {
        return View();
    }
//do something!
}

The view is:

@model MyProject.Models.MyViewModel

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    <div class="form-group">
        @Html.LabelFor(model => model.MyId , htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownList("MyId", null, "Select", htmlAttributes: new { @class = "form-control" })
            @Html.ValidationMessageFor(model => model.MyId, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.MyObject.Number, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.TextBoxFor(model => model.MyObject.Number, new { @class = "form-control", type = "number", min = "1", max = "3", step = "1" })
            @Html.ValidationMessageFor(model => model.MyObject.Number, "", new { @class = "text-danger" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(model => model.MyObject.Name , htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.TextBoxFor(model => model.MyObject.Name , new { @class = "form-control", type = "number", min = "1", max = "3", step = "1" })
            @Html.ValidationMessageFor(model => model.MyObject.Name , "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default" formaction="@Url.Action("Create")" />
        </div>
    </div>
}

When I post data to controller, it recognize the MyId value but don't fill MyObject parameter. Any suggests to how to post an object with ViewModel?


Solution

  • Assuming that you have @model MyViewModel at the top of the view, there's no need to complicate it.

    Make your submit on the view

    <input type="submit" value="Create" class="btn btn-default" />
    

    and change the signature of the post method

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(MyViewModel vm)
    {
        if (!ModelState.IsValid)
        {
            return View();
        }
    //do something!
    }
    

    The view model should then be bound.