MVC model post with partial shows list as null

Обновить

April 2019

Просмотры

102 раз

1

Я иду по кругу в настоящее время, так что если кто-нибудь может определить проблему здесь я бы очень признателен.

У меня есть частичный я использую, чтобы перечислить пункты и что работает отлично. Сообщение обратно в контроллер работает, если элементы, передаваемые обратно просто установить как IEnumerable от предметов, но мне нужно передать обратно модель, поскольку она содержит больше информации, чем просто список.

На этом список пуст каждый раз и я не могу понять, почему.

Частичный:

@model RequestModel

@section Scripts {
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet">
<style>
    .btn span.glyphicon {
        opacity: 0;
    }

    .btn.active span.glyphicon {
        opacity: 1;
    }

</style>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.min.js"></script>
}
@for (var i = 0; i < Model.Requests.Count(); i++)
{
    <div @(Model.Requests.Count == 3 ? "class=col-md-4" : Model.Requests.Count() == 2 ? "class=col-md-6" : "class=col-md-12")>
        @Html.HiddenFor(m => Model.Requests[i].RequestID)
        <table class="table table-responsive img-rounded">
            <thead>
                <tr class="alert-cascade">
                    <th colspan="2">
                        <div class="btn-group btn-group-sm pull-right" role="group" data-toggle="buttons">
                            <button class="btn btn-success" data-toggle="tooltip" title="Accept" id="acceptradio">
                                @Html.RadioButtonFor(m => Model.Requests[i].AcceptChecked, Model.Requests[i].AcceptChecked, new { @id = Model.Requests[i].RequestID, @style = "display:none" })
                                <span>Accept </span>
                                <span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
                            </button>
                            <button class="btn btn-warning" data-toggle="tooltip" title="Reject" id="rejectradio">
                                @Html.RadioButtonFor(m => Model.Requests[i].RejectChecked, Model.Requests[i].RejectChecked, new { @id = Model.Requests[i].RequestID, @style = "display:none" })
                                <span>Reject </span>
                                <span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
                            </button>
                        </div>
                        @Model.Requests[i].EmployeeDescription
                    </th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td><strong>Request Type</strong></td>
                    <td class="text-right">@Model.Requests[i].RequestType</td>
                </tr>
                <tr>
                    <td><strong>Duration</strong></td>
                    <td class="text-right">@Model.Requests[i].DurationDescription</td>
                </tr>
                <tr>
                    <td><strong>Dates</strong></td>
                    <td class="text-right">@Model.Requests[i].DatesDescription</td>
                </tr>
            </tbody>
        </table>

    </div>
}

Вид:

    @model RequestPageModel
@{
    ViewData["Title"] = "Requests";
    ViewData["SubTitle"] = "Welcome to Cascade Mobile";
}
@{Layout = "~/Views/Shared/_MainLayout.cshtml";}
@section Scripts {
    <script type="text/javascript">
        //Submit count setter
        $(document).ready(function () {
            var accepted = 0;
            var rejected = 0;
            $("#acceptradio").click(function () {
                console.log("ready 2!");
                $("#acceptCount").text("4");
            });
        });
</script>
}

<div class="container">
    <h3>@ViewBag.Warning</h3>
        @*Existing requests*@
        <h4><strong>Requests</strong> <span class="badge alert-cascade">@Model.Pager.TotalRecords</span></h4><br />
    @using (Html.BeginForm("Index", "Request", new { @id = "requestsform" }))
    {
        <div class="row">
            @Html.Partial("_MultiSelectPartial", Model.RequestModel)
        </div>
        <div>
            <textarea class="span6" rows="3" placeholder="Comments.." required></textarea>
        </div>
        <input type="submit" value="submit"/>
    }

    <button id="submitbtn" class="btn btn-primary pull-right" type="button">
        Accept 
        <span class="badge" id="acceptCount">0</span>
        Reject 
        <span class="badge" id="rejectCount">0</span>
    </button>
    @Html.Partial("_Pager", Model.Pager)
</div>

Действие контроллера:

[HttpPost]
        public IActionResult Index(RequestModel requests)
        {
            ViewBag.Warning = "We have: ";
            foreach (var request in requests.Requests)
            {
                ViewBag.Warning +=  request.RequestID + " : ** : ";
            }
            var requestModel = GetRequestPageModel(3,1);
            //requestModel.Requests[0].AcceptChecked = true;
            return View("~/Views/User/Requests.cshtml", requestModel);
        }

Модель:

using System;
using System.Collections.Generic;

namespace Mobile.Models
{
    /// <summary>
    /// Request data model for the requests page
    /// </summary>
    public class RequestModel
    {
        public List<Request> Requests;
        public RequestModel(List<Request> requests)
        {
            Requests = requests;
        }
        public RequestModel()
        {
            Requests = new List<Request>();
        }
    }
}

Опять же, если метод пост занимает только список запроса пунктов его прекрасных, но мне нужно будет передать больше информации и не может получить его, чтобы опубликовать список в качестве части модели. Может кто-нибудь увидеть, что случилось здесь?

1 ответы

1

The model in your partial is RequestModel and your loop is generating controls with

name="Requests[0].RequestID"
name="Requests[1].RequestID"

etc, but the model in your POST method should be RequestPageModel so the correct name attributes would need to be

name="RequestModel.Requests[0].RequestID"
name="RequestModel.Requests[1].RequestID"

which will post back to

[HttpPost]
public IActionResult Index(RequestPageModel model)

You need to change the model in the partial to @model RequestPageModel (and adjust the HtmlHelper methods accordingly) and in the main view, use @Html.Partial("_MultiSelectPartial", Model).

In addition, change the name of the parameter to (say) RequestModel model so there is no conflict with the equivalent property name (refer this answer for an explanation).

I would however recommend that you use custom EditorTemplate's for your types rather than a partial, so that you controls are correctly named (refer the 2nd part of this answer for an example)

Side notes:

  1. Your radio buttons do not makes sense, since they have different names so you can select both (and once selected, you cannot un-select them)
  2. Your have a <textarea> without a name attribute so it will not submit a value.