我如何将表单字段绑定到嵌套模型上的帖子?



我正在编写一个解决方案,用户将提交一个表单,将值返回到我的ASP。。NET MVC控制器。我的模型很复杂,表单字段包含在一个嵌套的对象中(我通过MediatR使用CQRS)。当我提交表单时,这些值会显示为空。如何使复杂模型识别表单字段?

下面是我的代码:

控制器:

[HttpPost]
[Route("edit")]
public async Task<IActionResult> Edit(UpdateApplicationCommand command)
{
await _mediator.Send(command)
.ConfigureAwait(false);
return RedirectToAction("Index");
}

模型:

public class UpdateApplicationCommand : IRequest<Unit>
{
public ApplicationEditGeneralViewModel ApplicationEditGeneralViewModel { get; set; } = null!;
}
public class ApplicationEditGeneralViewModel
{
[Required]
public string Name { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
}

视图:

@model ApplicationEditGeneralViewModel
<form method="post" asp-action="Edit" asp-controller="Applications">
<div class="form-floating mb-3">
@Html.TextBoxFor(m => m.Name, new { @class = "form-control", placeholder = "Application Name"})
<label for="Name">Application Name</label>
</div>
<div class="form-floating mb-3">
@Html.TextBoxFor(m => m.Description, new { @class = "form-control", placeholder = "Application Description"})
<label for="Description">Application Description</label>
</div>
<div class="d-flex flex-row-reverse bd-highlight">
<input type="submit" value="Submit" class="btn btn-primary mt-2" />
</div>
</form>

我试图通过将ApplicationEditGeneralViewModel的内容直接放入UpdateApplicationCommand类来减少复杂模型的字段。这是有效的,但我真的想保持嵌套结构,以便我可以重用ApplicationEditGeneralViewModel对象。

我在这里看到了这个解决方案:

  • 如何在局部视图中绑定嵌套模型

但是我宁愿避免为每个表单字段添加名称作为路由对象(如果可能的话)。还有其他更简单的方法吗?

第一种方法,您可以像下面这样自定义模型绑定:

public class CustomModelBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
throw new ArgumentNullException(nameof(bindingContext));
var model = new UpdateApplicationCommand()
{
ApplicationEditGeneralViewModel = new ApplicationEditGeneralViewModel()
{
Description = bindingContext.ValueProvider.GetValue("Description").ToString(),
Name = bindingContext.ValueProvider.GetValue("Name").ToString()
}
};
bindingContext.Result = ModelBindingResult.Success(model);
return Task.CompletedTask;
}
}

像下面这样应用自定义模型绑定:

[HttpPost]
public async Task<IActionResult> Edit([ModelBinder(typeof(CustomModelBinder))]UpdateApplicationCommand model)
{
//.....
}

第二种方法,只需更改剃刀视图,如下所示:

@model UpdateApplicationCommand
<form method="post">
<div class="form-floating mb-3">
@Html.TextBoxFor(m => m.ApplicationEditGeneralViewModel.Name, new { @class = "form-control", placeholder = "Application Name"})
<label for="Name">Application Name</label>
</div>
<div class="form-floating mb-3">
@Html.TextBoxFor(m => m.ApplicationEditGeneralViewModel.Description, new { @class = "form-control", placeholder = "Application Description"})
<label for="Description">Application Description</label>
</div>
<div class="d-flex flex-row-reverse bd-highlight">
<input type="submit" value="Submit" class="btn btn-primary mt-2" />
</div>
</form>

最新更新