【问题标题】:MVC model post with partial shows list as null部分显示列表为空的 MVC 模型帖子
【发布时间】:2016-12-16 09:48:06
【问题描述】:

我现在正在兜圈子,所以如果有人能在这里找出问题,我将不胜感激。

我有一个用来列出项目的部分,它工作正常。 如果传回的项目只是设置为项目的可枚举,则返回到控制器的帖子有效,但我需要传回一个模型,因为它包含的信息不仅仅是列表。

这样做时,列表每次都是空的,我不明白为什么。

部分:

@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>();
        }
    }
}

同样,如果 post 方法只接受请求项目的列表,那很好,但我需要传递更多信息,并且无法将列表作为模型的一部分发布。谁能看到这里有什么问题?

【问题讨论】:

    标签: c# asp.net-mvc-5 http-post


    【解决方案1】:

    您的部分模型是RequestModel,您的循环正在生成控件

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

    等等,但是你的 POST 方法中的模型应该是 RequestPageModel,所以正确的 name 属性需要是

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

    这将回发给

    [HttpPost]
    public IActionResult Index(RequestPageModel model)
    

    您需要将部分模型更改为@model RequestPageModel(并相应地调整HtmlHelper 方法)并在主视图中使用@Html.Partial("_MultiSelectPartial", Model)

    另外,将参数名称更改为(比如)RequestModel model,这样就不会与等效的属性名称冲突(请参阅this answer 的解释)。

    不过,我建议您为您的类型使用自定义 EditorTemplate 而不是部分类型,以便正确命名控件(例如,请参阅 this answer 的第二部分)

    旁注:

    1. 您的单选按钮没有意义,因为它们有不同的 名称,以便您可以同时选择两者(一旦选择,您就不能 取消选择它们)
    2. 您的&lt;textarea&gt; 没有name 属性,所以它不会 提交一个值。

    【讨论】:

    • 您好,RequestPageModel 是主要页面使用的,它包含 RequestModel,它只是请求列表加上一个文本字段。你的答案还会一样吗?部分视图不需要来自 RequestPageModel 的额外内容,只需要来自 RequestModel 的请求列表和文本值。我真的还需要通过整个事情吗?
    • 是的,我知道。但是为了回发textarea 的值,它需要一个name 属性并且POST 方法中的模型必须是RequestPageModel。并且您必须更改参数的名称。即使你想保留现有的POST方法和部分,你仍然必须将方法更改为public IActionResult Index(RequestModel anyNameExceptRequests, string theNameOfYourTextArea)
    • 嗨,我终于有这个工作了,不得不通过 RequestPageModel。我可以将操作保留为 RequestPage 并且表单仍然只使用 RequestPage 数据,但由于模型是 RequestPageModel 控件现在标记为:name="RequestModel.Requests[0].RequestID" name="RequestModel.Requests[1 ].RequestID" 这就是为什么它现在在回发上工作,因为名称是完全限定的。所以我想知道,如何修改命名约定以强制默认包含模型?甚至可以添加前缀,以便我可以使用模型设置名称。
    • 是的,这就是我的回答:)
    猜你喜欢
    • 1970-01-01
    • 2017-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多