为什么select asp-for在后处理程序中没有值

lmvvr0a8  于 2023-01-10  发布在  .NET
关注(0)|答案(1)|浏览(75)

我有这个表单在我的页面上。它是为了添加一些项目到DB。项目需要为自己的导演,所以我传递工人的SelectList到这个表单。

<form asp-controller="Project" asp-action="Edit" method="post">
...some other fields...
@if (ViewBag.workers != null)
    {
        <div>
            <label asp-for="director">Director</label>
            <select asp-for="director" asp-items=@ViewBag.workers>
            </select>
            <span asp-validation-for="director"></span>
        </div>
    }
...
</form>

选择标签工作,有我的工人。但当我试图提交,我有错误“* 导演字段是必需的。*”

我用js检查了表单,它有来自select选项的数据,但我的后处理程序没有。

有哈德勒的密码

[HttpPost]
    public IActionResult Edit(Project model)
    {
        // here model hasn't director field
        if (ModelState.IsValid)
        {
            dataManager.project.SaveProject(model);
            return RedirectToAction(nameof(HomeController.Index), nameof(HomeController).Replace("Controller", ""));
        }
        ViewBag.workers = new SelectList(dataManager.worker.GetAllWorkers(), nameof(Worker.id), nameof(Worker.name));
        return View(model);
    }

和项目类代码

public class Project
{
    [Required] public Guid id { set; get; }
    
    [Required] public string name { set; get; }
    
    public string customer { set; get; }

    public string executor { set; get; }

    public Worker director { set; get; }

    public DateTime start { set; get; }

    public DateTime end { set; get; }

    public uint priority { set; get; }
}
sqyvllje

sqyvllje1#

  • 将评论中提到的解决方案作为答案贴出来,以供未来读者参考。*
    • 问题和关注点**

从该行开始:

ViewBag.workers = new SelectList(dataManager.worker.GetAllWorkers(), nameof(Worker.id), nameof(Worker.name));

您将下拉列表选项的值设置为id。不确定id类型是什么(可能是intGuid类型),但我确定它不是Worker(对象)类型。
Project模型中,您将director指定为Worker类型。

public class Project
{
    ...

    public Worker director { set; get; }
}

由于int/Guid类型与Worker类型不匹配,因此API操作无法绑定从视图传递到模型的值。因此,您将在API操作中获得Project作为null

    • 解决方案**

1.建议将Project模型中的属性类型修改为int/Guid(取决于您在数据库中的工作者ID类型),而不是使用Worker(对象)类型。并删除不再需要的Worker属性,避免ModelState中由于未提供值而导致的错误。

  • 注意:如果此Project模型是由Entity Framework生成(搭建)的实体模型,建议创建另一个类作为DTO(数据传输对象)。然后将接收到的DTOMap到实体模型。*
public class Project
{
    ...

    public Worker directorId { set; get; }
}

1.在视图中,将下拉列表与asp-for="workerId"绑定,以将选定值作为workerId传递。

<select asp-for="directorId" asp-items=@ViewBag.workers></select>

1.后端侧
3.1.* * 要点**:用接收到的project.workerId查询Worker对象,然后将Worker对象绑定到实体模型上再插入。
3.2.(如果按照 * 1 * 中所述实现DTO)您需要实现逻辑(或查找Map库,如AutoMapper)以从DTOMap到实体模型。

相关问题