首页 > 解决方案 > 组合视图模型在提交后产生空字段

问题描述

如果我有两个模型类要组合成一个通用视图模型,如下所示:

public class PersonViewModel
{
    public string Name { get; set; }
}

public class GroupViewModel
{
    public string Name { get; set; }
}

public class PersonAndGroupViewModel
{
    public PersonViewModel Person { get; set; }
    public GroupViewModel Group { get; set; }
}

是否可以像这样通过一种通用的形式一次性将它们都保存到数据库中?

@model Solution.Models.PersonAndGroupViewModel
<form asp-action="SavePersonAndGroup">
    <input asp-for="Person.Name">
    <input asp-for="Group.Name">
    <button type="submit">Save</button>
</form>

public async Task<IActionResult> SavePersonAndGroup(
        [Bind("Group.Name,Person.Name")]
        PersonAndGroupViewModel model)
{
    if (ModelState.IsValid)
    {
        Person person = auto.Map<Person>(model.Person);
        Group group = auto.Map<Group>(model.Group);
        db.Add(Person);
        db.Add(Group);
        await db.SaveChangesAsync();
        return RedirectToAction("Details", "Groups", new { id = group.Id });
    }
    return View(model);
}

我已经尝试过了,但我无法让它工作。到达控制器方法时,这些字段为空。

标签: c#asp.net-core-mvcmodel-binding

解决方案


从 Asp.Net Core 3.1 开始,视图渲染引擎会执行此操作。当您想要将模型传递给表单时,相应输入字段的名称和 ID 会强烈保留其模型名称。例如

public class Person
{
    public string Name { get; set; }
}

将会

<input asp-for="Person.Name" id="Person.Name" name="Person.Name" />

因此,将这种情况与您想要实现的目标联系起来。您可以通过在输入类型上放置自己的 ID 和名称属性来覆盖此默认行为。您正在考虑的解决方法是创建一个可以容纳所有这些输入的股票。当然,这是 dtos 的肮脏工作。

public class PersonDto
{
    public string PersonName { get; set; }
}

public class GroupDto
{
    public string GroupName { get; set; }
}
public class PersonGroup
{
    public string PersonName { get; set; }
    public string GroupName { get; set; }
}
//Then in controller
PersonDto person = auto.Map<PersonDto>(model);
GroupDto group = auto.Map<GroupDto>(model);

推荐阅读