ASP.NET MVC5 无效的模型状态:如何将外键传递到下拉列表并将其传递回 HTTPPost
本文关键字:NET MVC5 下拉列表 HTTPPost 状态 模型 ASP 无效 | 更新日期: 2023-09-27 18:37:26
我有一个项目模型,如下所示:
public class Project
{
public int Id { get; set; }
....
[Required]
public virtual ApplicationUser Client { get; set; }
[Key]
[ForeignKey("Client")]
public string ClientID;
[Required]
public virtual ApplicationUser ProjectManager { get; set; }
[Key]
[ForeignKey("ProjectManager")]
public string ProjectManagerID;
....
}
在尝试将具有指定角色的用户传递到创建操作中,如下所示,使用 ViewBag:
// GET: /Project/Create
public ActionResult Create()
{
populateRoles();
SelectList PMs = new SelectList(projectManagers, "Id", "Name");
ViewBag.ProjectManagerID = PMs;
SelectList Clients = new SelectList(clients, "Id", "Name");
ViewBag.ClientID = Clients;
return View();
}
这是下拉菜单的剃刀视图部分:
<div class="form-group">
@Html.Label("Project Manager", new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.DropDownList("ProjectManagerID", ViewBag.ProjectManagerID as SelectList, new { @class = "col-md-10 control-label" })
</div>
</div>
<div class="form-group">
@Html.Label("Client", new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.DropDownList("ClientID", ViewBag.ClientID as SelectList, new { @class = "col-md-10 control-label" })
</div>
</div>
到目前为止没有问题,但是在表单发布中,我的模型将没有有效状态:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,Name,Progress,CreateDate")] Project project)
{
/*---------------------populate select lists ------*/
populateRoles();
SelectList PMs = new SelectList(projectManagers, "Id", "Name");
ViewBag.ProjectManagerID = PMs;
SelectList Clients = new SelectList(clients, "Id", "Name");
ViewBag.ClientID = Clients;
/*-----------try to fix invalid modelstate ---------*/
string projectManagerID = Request["PMs"];
string clientID = Request["Clients"];
project.ProjectManagerID = projectManagerID;
project.ClientID = clientID;
if (ModelState.IsValid) // <-Invalid modelstate because required foreign key properties
{
dbContext.Projects.Add(project);
dbContext.SaveChanges();
return RedirectToAction("Index");
}
return View(project);
}
问题:如何在此处传递所需的外键属性?
我不相信你在控制器中以正确的方式使用框架。使用请求项将抛弃 ASP.NET MVC 框架试图为您执行的所有操作。它实际上应该按照以下思路阅读:
[HttpPost]
public ActionResult Create(string submitButton)
{
var model = new MyClass(); // go and get the record you want to edit
if (submitButton == "Save")
{
TryUpdateModel(model);
if (!ModelState.IsValid) // if the modelstate isn't valid, setup the dropdowns for the return trip to the form
{
ViewData["OrganizationId"] = model.OrganizationId;
ViewBag.RecordTypes = GetRecordTypes(model.OrganizationId);
return View(model);
}
context.AddToMyType(model);
context.SaveChanges(); // save changes if there are no errors
}
return RedirectToAction("Index", new { id = model.OrganizationId });
}
现实情况是,您应该允许 MVC 处理几乎所有 ASP.NET 绑定。只有在非常特殊的情况下,您才应该覆盖它。
另外,正如 Shyju 在评论中所说,最佳实践表明您还应该为此使用专用视图模型,而不是域模型。
P.S. 撇开讲课(抱歉),您的代码不可操作的具体原因是在您调用 SaveChanges() 时未设置 ProjectManager 属性。您只设置了项目经理ID,这不会自动为您设置项目经理属性,如果您没有按照MVC中的预期使用绑定,则必须自己执行此操作。
祝你的应用好运!