Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Posting multiple forms on MVC Razor View with a Single View Model

I have a razor view that will contain 5 forms. (A, B, C, D, E). Each of these forms has their own ViewModel (AViewModel, BViewModel, CViewModel, DViewModel, EViewModel).

I created a parent ProductViewModel that the page will use as its only ViewModel. Within this ViewModel will be all of the other ViewModels for each form on the page (listed above).

Here is what the ProductViewModel's properties look like:

public AViewModel { get; set; }
public BViewModel { get; set; }
public CViewModel { get; set; }
public DViewModel { get; set; }
public EViewModel { get; set; }

My razor view looks like the following:

@model MVCApp.ViewModels.ProductViewModel

@{
    ViewData["Title"] = "Product Detail";
}

<h2>Product Detail</h2>

<form asp-controller="A" asp-action="Save" data-ajax="true" data-ajax-method="POST">
    <div class="form-horizontal">
        <h4>Form A</h4>
        <hr />
        <div asp-validation-summary="ModelOnly" class="text-danger"></div>
        <div class="form-group">
            <label asp-for="AViewModel.Name" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="AViewModel.Name" class="form-control"/>
                <span asp-validation-for="AViewModel.Name" class="text-danger" />
            </div>
        </div>
        <div class="form-group">
            <label asp-for="AViewModel.StartDate" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="AViewModel.StartDate" class="form-control"/>
                <span asp-validation-for="AViewModel.StartDate" class="text-danger" />
            </div>
        </div>
        <div class="form-group">
            <label asp-for="AViewModel.EndDate" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="AViewModel.EndDate" class="form-control"/>
            </div>
        </div>
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
</form>

<div>
    <a asp-action="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

When the Save button is clicked I end up in the Save (POST) Action Method of the A Controller just as I would expect:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public IActionResult Save(AViewModel viewModel)
    {
        return Ok();
    }

However, I noticed all of the properties of the viewModel param are empty.

Does this mean I really have to pass the ProductViewModel object as my ViewModel to the Save Action Method for all 5 of these forms where only the ViewModel in scope will be populated and everything else will be null? Or is there a better way?

like image 969
Blake Rivell Avatar asked Sep 07 '16 18:09

Blake Rivell


People also ask

Can we have 2 models in a single view?

In MVC we cannot pass multiple models from a controller to the single view.

Can one view have multiple controllers?

Yes, It is possible to share a view across multiple controllers by putting a view into the shared folder. By doing like this, you can automatically make the view available across multiple controllers.


Video Answer


1 Answers

I suggest make each form a partial view and pass in only the sub model needed from the parent model

 @{await Html.RenderPartialAsync("AViewPartial", Model.AViewModel); }

then your inputs in the partial can be changed from

<input asp-for="AViewModel.Name" class="form-control"/>

to

<input asp-for="Name" class="form-control"/>

which should make it bind correctly by the modelbinder so it gets passed into your action

like image 66
Joe Audette Avatar answered Oct 12 '22 06:10

Joe Audette