c# 如何接收两个模型并发送一个模型的表单?

c# How to recieve two models and send a form with one model?

首先,这是我的问题的简化版本。

我有两个模型:

问题是我需要两个模型。我有一个表格,我在 select 输入中显示类别,然后创建一个新的人。

在 .cshtml 中我有:

@using WebApiClient.Models
@model dynamic

<h1> Form: add a person with a category</h1>

<form asp-action="formMultiple" enctype="multipart/form-data" method="post">
    <label asp-for=@Model.Person.Name class="control-label">Name</label>
    <input asp-for="@Model.Person.Name" class="form-control" value= "@Model.Person.Name" />

    <label asp-for="Category" class="control-label">Category</label>
    <select asp-for="Category">
    @foreach (var item in Model.Category){
        <option value="Category">@item.NameCategory</option>
    }
    </select>
    <input type="submit" value="Add person" class="btn btn-primary" />
</form>

我在控制器中有:

public async Task<IActionResult> formMultiple()
        {
            dynamic d = new ExpandoObject();
            var categories = await _client.GetCategoriesAsync();
            d.categories = categories;
            d.person = new Person();
            return View(d);
        }
public async Task<ActionResult> formMultiple(Person person);

有什么办法解决这个问题吗? 谢谢 <3

根据以上评论:

CS1963 An expression tree may not contain a dynamic operation

不要依赖 dynamic 为您的视图模型。创建 classes 是微不足道的,它可以为您提供 C# 通常期望的所有静态类型安全性。 dynamic 可能是一个有用的工具,但不能 drop-in 替代您不想创建 class 的任何地方。

您的视图模型可以很简单(我猜是一个合理的名称):

public class CreatePersonVM
{
    public IEnumerable<Category> Categories { get; set; }
    public Person Person { get; set; }
}

那么您会希望在视图中键入:

@model CreatePersonVM

并从控制器提供:

var model = new CreatePersonVM();
model.Categories = await _client.GetCategoriesAsync();
model.Person = new Person();
return View(model);

只需确保 <form> 中的元素仍然创建一个 Person 对象,并且该表单仍然可以 post 该对象的值到 POST 操作。

有几个选项

  1. 使用具有两个属性的 ViewModel(一个用于人员,一个用于类别)- 最佳和推荐选项
  2. 使用包含两项的 ValueTuple(一项用于人员,一项用于类别)- 它应该用于少量数据
  3. 将人物模型发送到视图并在 ViewBag 或 ViewData 中包含类别
  4. 将人物模型发送到视图并调用 ajax 来填充类别下拉列表

所以我可以给你第二种方法的例子

控制器

public async Task<IActionResult> formMultiple()
{
    var categories = await _client.GetCategoriesAsync();
    var person = new Person();
    var model = (person, categories);
    return View(model );
}

查看

@using WebApiClient.Models
@model (Person person, List<Category> categories)

<h1> Form: add a person with a category</h1>

<form asp-action="formMultiple" enctype="multipart/form-data" method="post">
    <label asp-for=person.Name class="control-label">Name</label>
    <input asp-for="person.Name" name="@nameof(Model.person.Name)" class="form-control" />

    <label asp-for="person.Category" name="@nameof(Model.person.Category)" class="control-label">Category</label>
    <select asp-for="person.Category">
    @foreach (var item in Model.categories){
        <option value="@item.IdCategory">@item.NameCategory</option>
    }
    </select>
    <input type="submit" value="Add person" class="btn btn-primary" />
</form>
如果你可以分享你的Person和Category模型,那么我可以提供更精确的代码