使用 ViewModel 在数据库中保存 MVC 下拉列表项

Save MVC dropdownlist item in database using ViewModel

我是 MVC 架构的新手,需要帮助将下拉列表中的所选项目保存到数据库中。基本上对于创建视图上的每个项目模型,我需要有一个下拉列表,我需要在其中选择一个客户端(客户端名称显示在 Dropdonwlist 中)。根据所选择的客户端,ClientID 应该通过 Post 方法(作为外键)链接到数据库中的项目对象实例。

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 方法(使用来自客户端 table 的 Select 值填充下拉列表):

   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 部分,我收到错误 未将对象引用设置为对象的实例 。当我 post model => model.ClientId 如果我基本上通过这里任何其他内容,例如 model => model.Name 没有错误,只有客户端 ID 没有在数据库中成功 posted(很明显)。

这是 HTTP Post 的片段,这很可能是错误的:

[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();

        
    }

任何人都可以看看我的代码并帮助我识别:

我查看了几十个线程,不幸的是没有任何帮助。真的任何帮助将不胜感激。谢谢。

你必须修正动作

public IActionResult Create()
{

 var clients = _context.Client
           .Select(r =>  new SelectListItem{ Value= r.ClientId.ToString(), Text= r.Name)
           .ToList();

        var viewmodel = new CreateProjectViewModel
        {
            Clients = clients
             .... another properties
        };
        
        return View(viewmodel); 

    }

并查看

@Html.DropDownListFor(model => model.ClientId, @Model.Clients, "---Select Client---", new { @class = "form-control" })