模型作为 null 传递给 post 方法
model passed as null to the post method
首先,我尝试了网上搜索后遇到的所有解决方案,但没有任何效果。我的想法是按用户 ID 搜索,结果是权限和部门的两个复选框列表。默认情况下,如果用户有权访问该复选框,则会在表中选中该复选框。问题是从视图传递到 post 方法的模型为空。因此,如果我尝试 select 或更改任何内容并单击保存,则该模型没有来自 post 的任何值。我究竟做错了什么?我该如何更正它?
我的视图模型:
public class MainViewModel
{
public int SearchId { get; set; }
public List<UserPermissionViewModel> UserPermissions { get; set; }
public List<UserDepartmentViewModel> UserDepartments { get; set; }
}
public class UserDepartmentViewModel
{
public int DepId { get; set; }
public string DepName { get; set; }
public bool IsChecked { get; set; }
}
public class UserPermissionViewModel
{
public int PerId { get; set; }
public string PerName { get; set; }
public bool IsChecked_ { get; set; }
}
我的 post 控制器方法:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SaveData (MainViewModel model)
{
//remove existing user from the table in db
db.TBL_UserPermissions
.RemoveRange(db.TBL_UserPermissions
.Where(x => x.UserID == model.SearchId));
db.TBL_User_Dep_Access
.RemoveRange(db.TBL_User_Dep_Access
.Where(x => x.UserID == model.SearchId));
//adding what is selected from the checkboxes to the table in the db
foreach (var dep in model.UserDepartments)
{
if (dep.IsChecked)
{
TBL_User_Dep_Access tBL_User_Dep_ = new TBL_User_Dep_Access();
tBL_User_Dep_.UserID = model.SearchId;
tBL_User_Dep_.Dep_ID = dep.DepId;
tBL_User_Dep_.IsActive = true;
db.TBL_User_Dep_Access.Add(tBL_User_Dep_);
}
}
db.SaveChanges();
//adding what is selected from the checkboxes to the table in the db
foreach (var per in model.UserPermissions)
{
if (per.IsChecked_)
{
TBL_UserPermissions tBL_UserPermissions = new TBL_UserPermissions();
tBL_UserPermissions.UserID = model.SearchId;
tBL_UserPermissions.PermissionID = per.PerId;
tBL_UserPermissions.IsActive = true;
db.TBL_UserPermissions.Add(tBL_UserPermissions);
}
}
db.SaveChanges();
return View();
}
获取方法:
public ActionResult Index(int?SearchId)
{
var model = new MainViewModel();
var usr_Dep = db.TBL_User_Dep_Access
.Where(x => x.UserID == SearchId)
.Select(x => x.Dep_ID)
.ToList();
var usr_Per = db.TBL_UserPermissions
.Where(x => x.UserID == SearchId)
.Select(x => x.PermissionID)
.ToList();
if (SearchId != null)
{
List<UserDepartmentViewModel> Udep
= db.TBL_Department.Select(i =>
new UserDepartmentViewModel
{
DepId = i.Department_ID,
DepName = i.Department_Name,
IsChecked = usr_Dep.Contains(i.Department_ID)
}).ToList();
List<UserPermissionViewModel> Uper
= db.TBL_Permissions.Select(i =>
new UserPermissionViewModel
{
PerId = i.PermissionID,
PerName = i.PermissionName,
IsChecked_ = usr_Per.Contains(i.PermissionID)
}).ToList();
model.UserDepartments = Udep;
model.UserPermissions = Uper;
}
return View(model);
}
我的观点
@model Staff_Req.Models.MainViewModel
@using (Html.BeginForm("Index", "Access"))
{
@Html.AntiForgeryToken()
@Html.TextBox("SearchId", "", new { @id = "SearchId", @placeholder = "Search for...", @class = "form-control" })
<span class="input-group-btn">
<input class="btn btn-default" value="Search" type="submit">Go! />
</span>
}
@using (Html.BeginForm("SaveData", "Access", FormMethod.Post, new { id = "saveForm" }))
{
@Html.AntiForgeryToken()
<input type="hidden" name="model.SearchId" id="SaveData_SearchId" />
<ul>
@if (Model.UserDepartments != null)
{
for (int i = 0; i < Model.UserDepartments.Count(); i++)
{
@Html.CheckBoxFor(x => Model.UserDepartments[i].IsChecked)
@Html.DisplayFor(x => Model.UserDepartments[i].DepName)
@Html.HiddenFor(x => Model.UserDepartments[i].DepId)
}
}
</ul>
<ul>
@if (Model.UserPermissions != null)
{
for (int i = 0; i < Model.UserPermissions.Count(); i++)
{
@Html.CheckBoxFor(x => Model.UserPermissions[i].IsChecked_)
@Html.DisplayFor(x => Model.UserPermissions[i].PerName)
@Html.HiddenFor(x => Model.UserPermissions[i].PerId)
}
}
</ul>
<input type="submit" value="Save" class="btn btn-default" />
}
@section Scripts {
<script>
$("#saveForm").submit(function () {
$("#SaveData_SearchId").val($("#SearchId").val());
});
</script>
}
感谢任何帮助
您需要使用 [FromBody] 属性修饰 post 数据:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SaveData ([FromBody]MainViewModel model)
{
...
我有 运行 你的代码。我看到模型保留了 post 调用中的值。您需要在视图文件中进行以下更改。
@using (Html.BeginForm("SaveData", "Home", FormMethod.Post, new { id = "saveForm" }))
{
@Html.AntiForgeryToken()
@Html.HiddenFor(m => m.SearchId)
<ul>
@if (Model?.UserDepartments != null)
{
for (int i = 0; i < Model.UserDepartments.Count(); i++)
{
@Html.CheckBoxFor(x => x.UserDepartments[i].IsChecked)
@Html.DisplayFor(x => x.UserDepartments[i].DepName)
@Html.HiddenFor(x => x.UserDepartments[i].DepId)
}
}
</ul>
<ul>
@if (Model?.UserPermissions != null)
{
for (int i = 0; i < Model.UserPermissions.Count(); i++)
{
@Html.CheckBoxFor(x => x.UserPermissions[i].IsChecked_)
@Html.DisplayFor(x => x.UserPermissions[i].PerName)
@Html.HiddenFor(x => x.UserPermissions[i].PerId)
}
}
</ul>
<input type="submit" value="Save" class="btn btn-default" />
}
我相信这是一个简单的修复。我认为正在发生的事情是您的 SearchId 混淆了 modelBinder。
当我复制你的代码时,做了一个 post 并查看了表单数据下的网络选项卡,我看到了这个:
__RequestVerificationToken: T2O4PFE3MRyyVfj1nnnCTV2P6zgGe8-OPFXSvQTeU8fLI07zkQZk1vsKAKf6pzbLl0Df4Cd3VnT3C0XjmLeLWgaRcdXBY6BiXCWQjKjYuqw1
model.SearchId: 1
UserDepartments[0].IsChecked: true
UserDepartments[0].IsChecked: false
UserDepartments[0].DepId: 1
UserDepartments[1].IsChecked: true
UserDepartments[1].IsChecked: false
UserDepartments[1].DepId: 2
UserDepartments[2].IsChecked: false
UserDepartments[2].DepId: 3
UserPermissions[0].IsChecked_: true
UserPermissions[0].IsChecked_: false
UserPermissions[0].PerId: 1
UserPermissions[1].IsChecked_: true
UserPermissions[1].IsChecked_: false
UserPermissions[1].PerId: 2
UserPermissions[2].IsChecked_: false
UserPermissions[2].PerId: 3
看起来这让模型绑定器认为一切都将从模型开始。因为 SearchId 会。
所以要解决你的看法改变
<input type="hidden" name="model.SearchId" id="SaveData_SearchId" />
至此
<input type="hidden" name="SearchId" id="SaveData_SearchId" />
即删除模型。
那么它应该可以正常工作。
首先,我尝试了网上搜索后遇到的所有解决方案,但没有任何效果。我的想法是按用户 ID 搜索,结果是权限和部门的两个复选框列表。默认情况下,如果用户有权访问该复选框,则会在表中选中该复选框。问题是从视图传递到 post 方法的模型为空。因此,如果我尝试 select 或更改任何内容并单击保存,则该模型没有来自 post 的任何值。我究竟做错了什么?我该如何更正它?
我的视图模型:
public class MainViewModel
{
public int SearchId { get; set; }
public List<UserPermissionViewModel> UserPermissions { get; set; }
public List<UserDepartmentViewModel> UserDepartments { get; set; }
}
public class UserDepartmentViewModel
{
public int DepId { get; set; }
public string DepName { get; set; }
public bool IsChecked { get; set; }
}
public class UserPermissionViewModel
{
public int PerId { get; set; }
public string PerName { get; set; }
public bool IsChecked_ { get; set; }
}
我的 post 控制器方法:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SaveData (MainViewModel model)
{
//remove existing user from the table in db
db.TBL_UserPermissions
.RemoveRange(db.TBL_UserPermissions
.Where(x => x.UserID == model.SearchId));
db.TBL_User_Dep_Access
.RemoveRange(db.TBL_User_Dep_Access
.Where(x => x.UserID == model.SearchId));
//adding what is selected from the checkboxes to the table in the db
foreach (var dep in model.UserDepartments)
{
if (dep.IsChecked)
{
TBL_User_Dep_Access tBL_User_Dep_ = new TBL_User_Dep_Access();
tBL_User_Dep_.UserID = model.SearchId;
tBL_User_Dep_.Dep_ID = dep.DepId;
tBL_User_Dep_.IsActive = true;
db.TBL_User_Dep_Access.Add(tBL_User_Dep_);
}
}
db.SaveChanges();
//adding what is selected from the checkboxes to the table in the db
foreach (var per in model.UserPermissions)
{
if (per.IsChecked_)
{
TBL_UserPermissions tBL_UserPermissions = new TBL_UserPermissions();
tBL_UserPermissions.UserID = model.SearchId;
tBL_UserPermissions.PermissionID = per.PerId;
tBL_UserPermissions.IsActive = true;
db.TBL_UserPermissions.Add(tBL_UserPermissions);
}
}
db.SaveChanges();
return View();
}
获取方法:
public ActionResult Index(int?SearchId)
{
var model = new MainViewModel();
var usr_Dep = db.TBL_User_Dep_Access
.Where(x => x.UserID == SearchId)
.Select(x => x.Dep_ID)
.ToList();
var usr_Per = db.TBL_UserPermissions
.Where(x => x.UserID == SearchId)
.Select(x => x.PermissionID)
.ToList();
if (SearchId != null)
{
List<UserDepartmentViewModel> Udep
= db.TBL_Department.Select(i =>
new UserDepartmentViewModel
{
DepId = i.Department_ID,
DepName = i.Department_Name,
IsChecked = usr_Dep.Contains(i.Department_ID)
}).ToList();
List<UserPermissionViewModel> Uper
= db.TBL_Permissions.Select(i =>
new UserPermissionViewModel
{
PerId = i.PermissionID,
PerName = i.PermissionName,
IsChecked_ = usr_Per.Contains(i.PermissionID)
}).ToList();
model.UserDepartments = Udep;
model.UserPermissions = Uper;
}
return View(model);
}
我的观点
@model Staff_Req.Models.MainViewModel
@using (Html.BeginForm("Index", "Access"))
{
@Html.AntiForgeryToken()
@Html.TextBox("SearchId", "", new { @id = "SearchId", @placeholder = "Search for...", @class = "form-control" })
<span class="input-group-btn">
<input class="btn btn-default" value="Search" type="submit">Go! />
</span>
}
@using (Html.BeginForm("SaveData", "Access", FormMethod.Post, new { id = "saveForm" }))
{
@Html.AntiForgeryToken()
<input type="hidden" name="model.SearchId" id="SaveData_SearchId" />
<ul>
@if (Model.UserDepartments != null)
{
for (int i = 0; i < Model.UserDepartments.Count(); i++)
{
@Html.CheckBoxFor(x => Model.UserDepartments[i].IsChecked)
@Html.DisplayFor(x => Model.UserDepartments[i].DepName)
@Html.HiddenFor(x => Model.UserDepartments[i].DepId)
}
}
</ul>
<ul>
@if (Model.UserPermissions != null)
{
for (int i = 0; i < Model.UserPermissions.Count(); i++)
{
@Html.CheckBoxFor(x => Model.UserPermissions[i].IsChecked_)
@Html.DisplayFor(x => Model.UserPermissions[i].PerName)
@Html.HiddenFor(x => Model.UserPermissions[i].PerId)
}
}
</ul>
<input type="submit" value="Save" class="btn btn-default" />
}
@section Scripts {
<script>
$("#saveForm").submit(function () {
$("#SaveData_SearchId").val($("#SearchId").val());
});
</script>
}
感谢任何帮助
您需要使用 [FromBody] 属性修饰 post 数据:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SaveData ([FromBody]MainViewModel model)
{
...
我有 运行 你的代码。我看到模型保留了 post 调用中的值。您需要在视图文件中进行以下更改。
@using (Html.BeginForm("SaveData", "Home", FormMethod.Post, new { id = "saveForm" }))
{
@Html.AntiForgeryToken()
@Html.HiddenFor(m => m.SearchId)
<ul>
@if (Model?.UserDepartments != null)
{
for (int i = 0; i < Model.UserDepartments.Count(); i++)
{
@Html.CheckBoxFor(x => x.UserDepartments[i].IsChecked)
@Html.DisplayFor(x => x.UserDepartments[i].DepName)
@Html.HiddenFor(x => x.UserDepartments[i].DepId)
}
}
</ul>
<ul>
@if (Model?.UserPermissions != null)
{
for (int i = 0; i < Model.UserPermissions.Count(); i++)
{
@Html.CheckBoxFor(x => x.UserPermissions[i].IsChecked_)
@Html.DisplayFor(x => x.UserPermissions[i].PerName)
@Html.HiddenFor(x => x.UserPermissions[i].PerId)
}
}
</ul>
<input type="submit" value="Save" class="btn btn-default" />
}
我相信这是一个简单的修复。我认为正在发生的事情是您的 SearchId 混淆了 modelBinder。
当我复制你的代码时,做了一个 post 并查看了表单数据下的网络选项卡,我看到了这个:
__RequestVerificationToken: T2O4PFE3MRyyVfj1nnnCTV2P6zgGe8-OPFXSvQTeU8fLI07zkQZk1vsKAKf6pzbLl0Df4Cd3VnT3C0XjmLeLWgaRcdXBY6BiXCWQjKjYuqw1
model.SearchId: 1
UserDepartments[0].IsChecked: true
UserDepartments[0].IsChecked: false
UserDepartments[0].DepId: 1
UserDepartments[1].IsChecked: true
UserDepartments[1].IsChecked: false
UserDepartments[1].DepId: 2
UserDepartments[2].IsChecked: false
UserDepartments[2].DepId: 3
UserPermissions[0].IsChecked_: true
UserPermissions[0].IsChecked_: false
UserPermissions[0].PerId: 1
UserPermissions[1].IsChecked_: true
UserPermissions[1].IsChecked_: false
UserPermissions[1].PerId: 2
UserPermissions[2].IsChecked_: false
UserPermissions[2].PerId: 3
看起来这让模型绑定器认为一切都将从模型开始。因为 SearchId 会。
所以要解决你的看法改变
<input type="hidden" name="model.SearchId" id="SaveData_SearchId" />
至此
<input type="hidden" name="SearchId" id="SaveData_SearchId" />
即删除模型。
那么它应该可以正常工作。