我试图在一个View / Action中处理各种模型创作。
当s / o点击"新计算机" Type ViewModel接收类型为Computer的新对象。 View切换到不同的类型(在本例中为Computer),并根据传入的模型创建View。 这工作正常,但在提交表单(调用CreateComputer Action)时,并不是整个计算机对象都被传输 - 确切地说,与计算机相关的属性(两个枚举)都会丢失。我认为这是因为下拉列表的名称不是以硬件开头,而是被称为" FormType"和" PerformanceType"相反,这种情况有适当的解决方案吗?
澄清:
模型"计算机"继承自"硬件"。因为我想用一个VM处理所有创建,更新等等/ View ViewModel有一个名为Hardware类型硬件的属性。不幸的是,当使用VM作为Action参数时,属性Hardware始终是Hardware类型(尽管有时它应该是Computer类型)。此外,我的方法(部分)工作 - 模型绑定器似乎足够智能绑定到嵌套类型硬件。
我想要什么?
在Action中我希望Method能够确定传入的参数是Hardware类型还是类型Computer(继承表单硬件)并让Controller为确定的模型执行它的操作。换句话说:我想避免为不同的模型创建不同的动作,例如" CreateComputer(计算机计算机)"和" CreateGeneric(硬件硬件)"。
型号:
计算机:
namespace UserChange.com.Models
{
public class Computer : Hardware
{
public PerformanceType PerformanceType { get; set; }
public FormType FormType { get; set; }
public override HardwareType GetHardwareType()
{
return HardwareType.Computer;
}
public override string ToString()
{
return $"Computer: {base.ToString()}";
}
}
}
显示器:
using System.ComponentModel.DataAnnotations;
namespace UserChange.com.Models
{
public class Monitor : Hardware
{
[Required]
public short Size { get; set; }
[Required]
public MonitorColor MonitorColor { get; set; }
public override HardwareType GetHardwareType()
{
return HardwareType.Monitor;
}
public override string ToString()
{
return "Monitor: " + base.ToString();
}
}
}
设备:
[Table("NEOV_Hardware")]
public class Hardware : BaseModel
{
[Required]
[StringLength(50)]
public string Description { get; set; }
public bool IsVisible { get; set; }
public virtual HardwareType GetHardwareType()
{
return HardwareType.Generic;
}
public override string ToString()
{
return Description;
}
}
控制器:
[HttpPost]
public ActionResult CreateComputer(Computer hardware)
{
var uow = new UnitOfWork(new ApplicationContext());
uow.HardwareRepository.Add(hardware);
uow.Save();
return RedirectToAction("Index");
}
查看:
@using UserChange.com.Models
@using UserChange.dal.Repository.Interface
@model UserChange.ViewModels.NewHardwareViewModel
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
@{
switch (Model.Hardware.GetHardwareType()) {
case HardwareType.Computer:
<h2>New Computer</h2>
using (Html.BeginForm("CreateComputer", "Hardware", FormMethod.Post)) {
<table class="table table-hover table-bordered table-striped table-condensed">
<tr>
<td>Model name:</td>
<td>@Html.TextBoxFor(o => o.Hardware.Description)</td>
</tr>
<tr>
<td>Form factor:</td>
<td>@Html.EnumDropDownListFor(o => (o.Hardware as Computer).FormType)</td>
</tr>
<tr>
<td>Performance type:</td>
<td>@Html.EnumDropDownListFor(o => (o.Hardware as Computer).PerformanceType)</td>
</tr>
<tr>
<td>Comment:</td>
<td>@Html.TextAreaFor(o => o.Hardware.Comment)</td>
</tr>
</table>
<input type="submit" value="Submit" class="btn btn-primary" />
}
break;
case HardwareType.Monitor:
<h2>New Monitor</h2>
using (Html.BeginForm("CreateMonitor", "Hardware", FormMethod.Post)) {
<table class="table table-hover table-bordered table-striped table-condensed">
<tr>
<td>Model name:</td>
<td>@Html.TextBoxFor(o => o.Hardware.Description)</td>
</tr>
<tr>
<td>Size:</td>
<td>@Html.TextBoxFor(o => (o.Hardware as Monitor).Size)</td>
</tr>
<tr>
<td>Color:</td>
<td>@Html.EnumDropDownListFor(o => (o.Hardware as Monitor).MonitorColor)</td>
</tr>
<tr>
<td>Comment:</td>
<td>@Html.TextAreaFor(o => o.Hardware.Comment)</td>
</tr>
</table>
<input type="submit" value="Submit" class="btn btn-primary" />
}
break;
case HardwareType.Generic:
<h2>New Generic device</h2>
using (Html.BeginForm("CreateGeneric", "Hardware", FormMethod.Post)) {
<table class="table table-hover table-bordered table-striped table-condensed">
<tr>
<td>Model name:</td>
<td>@Html.TextBoxFor(o => o.Hardware.Description)</td>
</tr>
<tr>
<td>Comment:</td>
<td>@Html.TextAreaFor(o => o.Hardware.Comment)</td>
</tr>
</table>
<input type="submit" value="Submit" class="btn btn-primary" />
}
break;
}
}
**编辑1:** - 缺少虚拟机
public class NewHardwareViewModel : BaseViewModel
{
public Hardware Hardware { get; set; }
public NewHardwareViewModel(Hardware hardware, bool isUserAuthorized) : base(isUserAuthorized)
{
Hardware = hardware;
}
public NewHardwareViewModel(){ }
}