【发布时间】:2022-01-01 22:28:20
【问题描述】:
我对 MVC 架构完全陌生,需要帮助将下拉列表选择的项目保存在数据库中。基本上,对于其创建视图上的每个项目模型,我都需要一个下拉列表,我需要在其中选择一个客户端(客户端名称显示在 Dropdonwlist 中)。根据选择的客户端,ClientID 应该通过 Post 方法(作为外键)链接到数据库中的 Project 对象实例。
GET 部分显示Create 并填充Dropdownlist 工作,POST 是折磨我的东西。
这是我的项目模型:
public class Project
{
[Key]
public int ProjectId { get; set; }
public string Name { get; set; }
public string Budget { get; set; }
public string BusinessCase { get; set; }
[DataType(DataType.Date)]
public string StartDate { get; set; }
[DataType(DataType.Date)]
public string FinishDate { get; set; }
public int ClientId { get; set; }
public Client Client { get; set; }
public ICollection<ProjectMember> ProjectMembers { get; set; }
public Project()
{
}
}
这是我的客户端模型:
public class Client
{
[Key]
public int ClientId { get; set; }
public string Name { get; set; }
public string State { get; set; }
public string Address { get; set; }
public int VAT { get; set; }
public ICollection<Project> Projects { get; set; }
public Client()
{
}
}
这是我的 CreateProject ViewModel(某些属性可能不需要 - 我刚刚尝试了很多方法......)
public class CreateProjectViewModel
{
[Key]
public int ProjectId { get; set; }
public string Name { get; set; }
public string Budget { get; set; }
public string BusinessCase { get; set; }
[DataType(DataType.Date)]
public string StartDate { get; set; }
[DataType(DataType.Date)]
public string FinishDate { get; set; }
public int ClientId { get; set; }
public Client Client { get; set; }
public ICollection<ProjectMember> ProjectMembers { get; set; }
public IEnumerable<SelectListItem> Clients { get; set; }
}
这是我用于创建的控制器 GET 方法(使用从客户端表中选择值填充下拉列表):
public IActionResult Create()
{
var clients = _context.Client.Select(r => r.Name);
var viewmodel = new CreateProjectViewModel
{
Clients = new SelectList(clients)
};
return View(viewmodel);
}
最后,这是使用 CreateProjectViewModel 创建视图:
@model ProjectPortfolioApp.ViewModels.CreateProjectViewModel
@{
ViewData["Title"] = "Create";
}
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
@Html.LabelFor(model => model.Client.Name, htmlAttributes: new { @class = "control label col-md-2" })
**@Html.DropDownListFor(model => model.ClientId, Model.Clients, "---Select Client---", new { @class = "form-control" })**
</div>
上面的代码可以很好地使用public IEnumerable<SelectListItem> Clients { get; set; } 按预期显示下拉元素(客户端名称)。我正在苦苦挣扎的是 POST 部分,我收到错误 Object reference not set to an instance of an object。当我发布 model => model.ClientId 时,如果我基本上通过这里其他任何内容,例如 model => model.Name,则没有错误,只有客户端 ID 没有成功发布到数据库中(显然)。
这是 HTTP Post 的 sn-p,很可能是错误的:
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create(CreateProjectViewModel model)
{
if (ModelState.IsValid)
{
var project = new Project() { Name = model.Name, ClientId = model.ClientId, Budget = model.Budget, BusinessCase = model.BusinessCase, StartDate = model.StartDate, FinishDate = model.FinishDate };
_context.Add(project);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View();
}
任何人都可以查看我的代码并帮助我识别:
- 我的 GET Create 构造是否可以很好地服务于 POST Create 的目的
- 应该在@Html.DropDownListFor 中作为有效参数传递给 避免错误?
- HTTP Post Create 应该是什么样的?
我查看了几十个线程,不幸的是没有任何帮助。真的任何帮助将不胜感激。谢谢。
【问题讨论】:
-
也许您需要使用 SelectList 的构造函数,它告诉在 SelectList 中要使用的 ValueField 是什么。 docs.microsoft.com/en-us/dotnet/api/… 如果您使用浏览器工具 (F12) 并检查显示的下拉列表,您是看到值还是只有文本字段?
-
你好史蒂夫,在检查页面时它看起来像这样:
-
它应该是这样的 在我发布的链接中尝试构造函数并使用值和字段名称以及来自客户端类的描述
-
非常感谢!这真的奏效了。现在检查后的 HTML 看起来像 并正确存储在 DB 中。
标签: c# asp.net-mvc model-view-controller viewmodel html.dropdownlistfor