MVC模型作为null传递给视图

时间:2014-05-12 00:24:25

标签: c# asp.net-mvc asp.net-mvc-4

我收到的下面的视图是在收到一个非空的模型,因为表中正在填充数据,然后当我点击提交按钮触发下面的Controller方法时,传递控制器方法的模型是被传递为null。

我做错了什么?我一直试图解决这个问题几个小时,为什么会发生这种情况,为什么模型没有被传递给控制器​​方法,因为我100%确定模型不是null?

控制器方法:

    [HttpPost]
    public ActionResult AssignRole(PageDetailsModel model)
    {
        //controller method here which is not being executed since model being passed is null
    }

查看:

    @model OnlineLearningLTD.Models.PageDetailsModel

    @{
            ViewBag.Title = "Page Details";
    }

    <h2>Page Details</h2>

    <table class="table table-hover">
    @using (Html.BeginForm("AssignRole", "Page", FormMethod.Post))
    {
        if (Model.CurrPage != null)
        {

            <tr>
                <td>Name</td><td>@Model.CurrPage.Name</td>
            </tr>
            <tr>
                <td>Url</td><td>@Model.CurrPage.Url</td>
            </tr> 
            <tr>
                <td>Assigned Roles:</td>
                @foreach(var role in @Model.CurrPage.Role)
                {
                    <td>@role.Name</td>
                }
            </tr>     

            <tr>
                <td colspan="2"><h3>Assign Role</h3></td>
            </tr>
            <tr>
                <td>Choose Role</td>
                <td>
                 @Html.DropDownListFor(model => model.RoleId, Model.RoleList)

                </td>
            </tr>       
            <tr>
                <td colspan="2" align="right">
                     @if(Model.RoleList.Count() > 0)
                    {
                        <input type="submit" value="Assign Role" id = "btnAssignRole"/>
                    }
                    else
                    {
                        <label>There are no roles to be assigned</label>
                     }                
                </td>
            </tr>


        }
    }

型号:

public class PageDetailsModel
    {

        public SelectList RoleList { get; set; }
        public int RoleId { get; set; }

        public SelectList AssignedRoleList { get; set; }
        public int DeassignRoleID { get; set; }

        public CommonLayer.Page CurrPage { get; set; }

        public string PageID { get; set; }

        public PageDetailsModel() { }

        public PageDetailsModel(string pageID)
            : this()
        {
            this.PageID = pageID;
            CurrPage = new BusinessLayer.Pages().getPageByID(pageID);

            BusinessLayer.Roles role = new BusinessLayer.Roles();
            AssignedRoleList = new SelectList(role.getAllPageRoleWithPageID(pageID), "Id", "Name");
            RoleList = new SelectList(role.getAllPageRolesByPageId(pageID), "Id", "Name");
        }

    }

3 个答案:

答案 0 :(得分:1)

你可以看看几件事。查看html时这些属性有哪些名称?它们是否遵循默认模型绑定器的正确约定?您还可以在调试时查看HttpContext.Current.Request下的表单值。你看到像RoleId这样的所有值吗?如果名称格式不正确,您可能需要在视图中更改它们。如果不可能,请考虑使用自定义模型绑定器。这里有ASP.Net MVC Custom Model Binding explanationCode Project Link的几个资源 {{3}}

答案 1 :(得分:0)

要进行调试,请将控制器参数更改为FormCollection,如下所示:

 public ActionResult AssignRole(FormCollection formValues)

通过这样做,您可以看到实际从表单发回的内容。 MVC只不过是聪明的管道,试图通过表单回发信息来填充模型对象。如果它不存在于FormCollection中,它就不会受到模型属性的约束。

马上,我发现回发给控制器的唯一值是下拉列表中所选角色的RoleID。所有其他值都以原始文本或HTML格式注入页面,并且它们不会绑定到帖子中。

如果在表单主体的某处添加@ Html.HiddenFor(model =&gt; model.PageID,Model.PageID),则传递给控制器​​的模型将包含RoleID和PageID。这应该足以执行功能(分配角色)并重建要传递回视图的模型。

答案 2 :(得分:0)

只有RoleID会在您的代码中发布。使用输入和选择字段过帐值。您使用的唯一输入字段是Role -selectlist。不发布纯文本,例如td-tags中的文本。

您需要为要发布的其他字段添加隐藏的输入。您可以使用HiddenFor和Hidden html助手。

@model OnlineLearningLTD.Models.PageDetailsModel

@{
        ViewBag.Title = "Page Details";
}

<h2>Page Details</h2>

<table class="table table-hover">
@using (Html.BeginForm("AssignRole", "Page", FormMethod.Post))
{
    if (Model.CurrPage != null)
    {

        <tr>
            <td>Name  @Html.HiddenFor(model => model.CurrPage.Name</td>
            <td>@Model.CurrPage.Name</td>
        </tr>
        <tr>
            <td>Url @Html.HiddenFor(model => model.CurrPage.Url</td>
            <td>@Model.CurrPage.Url</td>
        </tr> 
        <tr>
            <td>Assigned Roles:</td>
            @foreach(var role in @Model.CurrPage.Role)
            {
                <td>@role.Name</td>
            }
        </tr>     

        <tr>
            <td colspan="2"><h3>Assign Role</h3></td>
        </tr>
        <tr>
            <td>Choose Role</td>
            <td>
             @Html.DropDownListFor(model => model.RoleId, Model.RoleList)

            </td>
        </tr>       
        <tr>
            <td colspan="2" align="right">
                 @if(Model.RoleList.Count() > 0)
                {
                    <input type="submit" value="Assign Role" id = "btnAssignRole"/>
                }
                else
                {
                    <label>There are no roles to be assigned</label>
                 }                
            </td>
        </tr>
    }
}

现在,如果您想发布CurrPage.Role集合,则需要使用for-loop而不是foreach。这将确保输入正确命名,并且模型绑定器可以解析模型。

    <tr>
            <td>Assigned Roles:</td>
            @for (int i = 0; i < Model.CurrPage.Role.Count(); i++)
            {
                <td>
                   @Html.HiddenFor(model => model.CurrPage.Role[i])
                   @role.Name
                </td>
            }
    </tr>