C# MVC, Link Together Nested Partial Views

2019-08-23 01:40发布

In a C# MVC WebApp, I have a CallDetailViewModel that contains a list of CallerViewModels and it has a List of PhoneNumberViewModels. I'm trying to link them all together properly.

Not shown here, but I am also trying to both load existing values and add new/remove values, so I don't know what's being sent to the controller ahead of time.

I've tried following this 2012 guide that has a very similar problem I found online, but no luck yet: Code Project Article
I also tried moving the List of PhoneNumberViewModels to the CallDetailViewModel, and while I was able to pass the phone numbers to my controller I didn't have a clear way to link them to the appropriate CallerViewModel.

I want to be able to add and remove PhoneNumbers from Callers and Callers from the CallDetail.
I've removed my buttons and AJAX regarding those for now, as it's not my main problem.

Here are my simplified ViewModels and Views:

ViewModels

CallDetailViewModel.cs

namespace PROJECT_NAME.ViewModels
{
    public class CallDetailsViewModel
    {
        public Guid Id { get; set; }

        public string EnteredByEmail { get; set; }

        public List<CallerViewModel> CallerViewModels { get; set; }
    }
}

CallerViewModel.cs

namespace PROJECT_NAME.ViewModels
{
    public class CallerViewModel
    {
        public Guid Id { get; set; }

        public string FirstName { get; set; }

        public List<PhoneNumberViewModel> PhoneNumberViewModels { get; set; }
    }
}

PhoneNumberViewModel.cs

namespace PROJECT_NAME.ViewModels
{
    public class PhoneNumberViewModel
    {
        public Guid Id { get; set; }

        public string Number { get; set; }
    }
}

Views

CallDetail.cshtml

@using PROJECT_NAME.ViewModels
@model CallDetailsViewModel

<div class="container">
    @using (Html.BeginForm("SubmitCallDetails", "Home", FormMethod.Post))
    {
        @Html.AntiForgeryToken()
        @Html.HiddenFor(m => m.Id)
        <div class="well">
            @* Call Details *@
            <div class="row">
                <fieldset">
                    <legend>Call Details</legend>
                </fieldset>
                <div class="form-group">
                    @Html.LabelFor(m => m.EnteredByEmail, new {@class = "control-label"})
                    @Html.TextBoxFor(m => m.EnteredByEmail, new {@class = "form-control"})
                </div>
            </div>
            @* Caller Details *@
            <div class="row">
                <fieldset>
                    <legend>Callers</legend>
                </fieldset>
            </div>
            @* Render each existing caller. Each caller gets it's own well to create a visual seperation between them. *@
            @if (Model.CallerViewModels.Count == 0)
            {
                <div class="well">
                    @{ Html.RenderPartial("_PartialCallerInfo", new CallerViewModel());}
                </div>
            }
            @foreach (var callerViewModel in Model.CallerViewModels)
            {
                <div class="well">
                    @{ Html.RenderPartial("_PartialCallerInfo", callerViewModel); }
                </div>
            }
        </div>
        <div class="row">
            <div class="form-group">
                <button class="btn btn-danger" type="reset">Reset</button>
            </div>
            <div class="form-group">
                <button class="btn btn-primary" type="submit">Submit</button>
            </div>
        </div>
    }
</div>

_PartialCallerInfo.cshtml

@using PROJECT_NAME.ViewModels
@model CallerViewModel

@using (Html.BeginCollectionItem("CallerViewModels"))
{
    <div class="row">
        @Html.HiddenFor(m => m.Id)
        <div class="form-group">
            @Html.LabelFor(m => m.FirstName, new { @class = "control-label" })
            @Html.TextBoxFor(m => m.FirstName, new { @class = "form-control"})
        </div>
    </div>
    @if (Model.PhoneNumberViewModels.Count == 0)
    {
        @{ Html.RenderPartial("_PartialCallerPhoneNumber", new PhoneNumberViewModel());}
    }
    @foreach (var phoneNumberViewModel in Model.PhoneNumberViewModels)
    {
        @{ Html.RenderPartial("_PartialCallerPhoneNumber", phoneNumberViewModel); }
    }
}

_PartialCallerPhoneNumber.cshtml

@using PROJECT_NAME.ViewModels
@model PhoneNumberViewModel

@using (Html.BeginCollectionItem("PhoneNumberViewModels"))
{
    <div class="row">
        @Html.HiddenFor(m => m.Id)
        <div class="form-group">
            @Html.LabelFor(m => m.Number, new { @class = "control-label" })
            @Html.TextBoxFor(m => m.Number, new { @class = "form-control"})
        </div>
    </div>
}

0条回答
登录 后发表回答