我收到的下面的视图是在收到一个非空的模型,因为表中正在填充数据,然后当我点击提交按钮触发下面的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");
}
}
答案 0 :(得分:1)
你可以看看几件事。查看html时这些属性有哪些名称?它们是否遵循默认模型绑定器的正确约定?您还可以在调试时查看HttpContext.Current.Request下的表单值。你看到像RoleId这样的所有值吗?如果名称格式不正确,您可能需要在视图中更改它们。如果不可能,请考虑使用自定义模型绑定器。这里有ASP.Net MVC Custom Model Binding explanation和Code 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>