.NET EF 4.7.2 MVC Create 方法转换子表单提交
Posted
技术标签:
【中文标题】.NET EF 4.7.2 MVC Create 方法转换子表单提交【英文标题】:.NET EF 4.7.2 MVC Create method converts child form submission 【发布时间】:2021-12-19 04:53:31 【问题描述】:我正在尝试使用 EF 4.7.2 和继承为我的 PC 组件 ASP.NET MVC 应用程序实现创建功能,以便在单个方法中处理所有派生类。
问题在于提交Component_CreateCPU.cshtml
表单会将CPU
的派生类在/Components/Create
操作中转换为其基类Component
。
我测试了在Index()
中实例化一个新的CPU
对象并将其传递给Create()
方法并保留它的派生类。
有什么方法可以提交视图表单并确保派生类被传入?
模型类:
public class Component : Interfaces.IComponent
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id get; set;
[DisplayName("Name")]
public string Name get; set;
[DisplayName("Description")]
public string Description get; set;
[DisplayName("Price")]
public decimal Price get; set;
public Manufacturer Manufacturer get; set;
public class CPU : Component
[DisplayName("Core Count")]
public int CoreCount get; set;
[DisplayName("Core Clock")]
public string CoreClock get; set;
创建局部视图
_Component_CreateCPU.cshtml
:
@model PCDB.Models.Components.CPU
@using (Html.BeginForm("Create", "Components", FormMethod.Post))
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>CPU</h4>
<hr />
@Html.ValidationSummary(true, "", new @class = "text-danger" )
<div class="form-group">
@Html.LabelFor(model => model.Name, htmlAttributes: new @class = "control-label col-md-2" )
<div class="col-md-10">
@Html.EditorFor(model => model.Name, new htmlAttributes = new @class = "form-control" )
@Html.ValidationMessageFor(model => model.Name, "", new @class = "text-danger" )
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Description, htmlAttributes: new @class = "control-label col-md-2" )
<div class="col-md-10">
@Html.EditorFor(model => model.Description, new htmlAttributes = new @class = "form-control" )
@Html.ValidationMessageFor(model => model.Description, "", new @class = "text-danger" )
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Price, htmlAttributes: new @class = "control-label col-md-2" )
<div class="col-md-10">
@Html.EditorFor(model => model.Price, new htmlAttributes = new @class = "form-control" )
@Html.ValidationMessageFor(model => model.Price, "", new @class = "text-danger" )
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.CoreCount, htmlAttributes: new @class = "control-label col-md-2" )
<div class="col-md-10">
@Html.EditorFor(model => model.CoreCount, new htmlAttributes = new @class = "form-control" )
@Html.ValidationMessageFor(model => model.CoreCount, "", new @class = "text-danger" )
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.CoreClock, htmlAttributes: new @class = "control-label col-md-2" )
<div class="col-md-10">
@Html.EditorFor(model => model.CoreClock, new htmlAttributes = new @class = "form-control" )
@Html.ValidationMessageFor(model => model.CoreClock, "", new @class = "text-danger" )
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
<div>
@Html.ActionLink("Back to List", "Index")
</div>
ComponentsController
:
public class ComponentsController : Controller
private readonly IComponentRepository<Component> _componentRepository;
public ComponentsController()
_componentRepository = new ComponentsRepository<Component>();
public ActionResult Index()
return View(_componentRepository.GetAll());
[Authorize(Roles = "Admin")]
public ActionResult Create()
return View(new ComponentCreateViewModel());
[Authorize(Roles = "Admin")]
[HttpPost]
public ActionResult Create(Component component)
if (ModelState.IsValid)
_componentRepository.Insert(component);
_componentRepository.Save();
return Content("Success");
【问题讨论】:
【参考方案1】:当您将表单发布到控制器时,浏览器不会序列化实体,它只是传递与您的控制器方法接受的对象的属性相结合的字段,或者其中参数的字段名称控制器方法。
因此,在您的情况下,您的控制器需要一个基类组件,这就是它将接收的全部内容,而不是 CPU 或其他子类的实例。 (虽然可能值得测试如果 Component 是 abstract
会发生什么)我的建议是实现每个子类的方法。如果有适用于组件级别的位,则在接收子类后将这些位通过传递给通用方法:
[Authorize(Roles = "Admin")]
[HttpPost]
public ActionResult CreateCPU(CPU cpu)
if (ModelState.IsValid)
_componentRepository.Insert(cpu);
_componentRepository.Save();
return Content("Success");
ComponentRepository 仍然可以接受 Insert(Component)
,前提是它最终可以确保引用正确的 DbSet
,或者 DbContext.Entity<T>
将解析传入的 CPU 与其他组件。
【讨论】:
感谢您的回复 - 为每个子类型实现一个方法似乎是最好的方法!出于好奇,我尝试将Component
设为抽象类,但在尝试将CPU
提交给Create(Component component)
时它破坏了应用程序以上是关于.NET EF 4.7.2 MVC Create 方法转换子表单提交的主要内容,如果未能解决你的问题,请参考以下文章
构建ASP.NET MVC5+EF6+EasyUI 1.4.3+Unity4.x注入的后台管理系统(55)-工作流设计-表单布局
MVC5+EF6简单实例---以原有SQLServer数据库两表联合查询为例
Microsoft 'Identity Platform' 是不是(轻松)与'(ASP.NET) Identity Framework' - MVC5 & .NET 4.7.2 集成?