【问题标题】:How to set up views and controller methods for binding models with inheritance?如何设置视图和控制器方法来绑定模型与继承?
【发布时间】:2014-03-07 16:53:47
【问题描述】:

假设我有一个 Vehicle 类和两个子类,如下所示:

public class Vehicle
{
    public string Model { get; set; }
    public string Color { get; set; }
}

public class Car : Vehicle
{
    public string Seats { get; set; }
}

public class Truck : Vehicle
{
    public string MaxLoad { get; set; }
}

我创建汽车或卡车的视图包含一个下拉列表,您可以在其中选择汽车或卡车,并根据您选择的内容将正确的表单加载到带有查询的 div 中。

我是这样实现的:

  • 我创建了一个局部视图,其中包含一个表单,用于创建具有 Model、Color 和 Seats 输入的汽车。
  • 另一个部分视图,其中包含用于创建具有模型、颜色和 MaxLoad 输入的卡车的表单。
  • 每个表单都提交给自己的控制器方法,即:

    [HttpPost] 公共 ActionResult CreateCar(汽车 newCar) { …… }

CreateTruck 也是如此。

  • 我有一个 createVehicle 视图,其中包含下拉列表、一个带有 id 的空 div 和一些将汽车或卡车部分视图加载到 div 中的 jquery 代码。

现在一切正常,但如果我需要更改我的车辆模型中的某些内容,我将不得不更改每个局部视图和每个控制器方法。

那么我要问的是,在这种情况下,我该如何实施提交模型的最佳方式?

最好是:

  • 我发布模型的一种控制器方法
  • createVehicle 视图包含 Vehicle 属性,每个局部视图仅包含自己的附加属性。

【问题讨论】:

  • 这些是 ViewModel 还是领域模型?
  • FWIW,给视图模型加上 ViewModelVM 后缀通常是个好主意,所以很明显它们不是实体。

标签: asp.net asp.net-mvc asp.net-mvc-4 razor asp.net-mvc-5


【解决方案1】:

如果你有这样的 ViewModel:

public class VehicleViewModel
{
  public Vehicle Vehicle { get; set; }
  public string Action { get; set; }
}

public class AddTruckModel
{
  public Truck Truck { get; set; }
}

public class AddCarModel
{
  public Car Car { get; set; }
}

在你做的控制器中(非常粗略的例子):

public ActionResult(int? vehicleType)
{
  var model = new VehicleViewModel;
  if (!vehicleType.hasValue || vehicleType.Value == 1)
  {
    model.Vehicle = new Car();
    model.Action = "AddCar";
  }
  else
  {
    model.Vehicle = new Truck()
    model.Action = "AddTruck";
  }

  if (Request.IsAjaxRequest())
  { 
    return Partial(model);
  }
  return View(model);
}

public ActionResult AddCar(AddCarModel model)
{
}

public ActionResult AddTruck(AddTruckModel model)
{
}

你使用这样的视图:

@model VehicleViewModel

@using(html.BeginForm(Model.Action, "Vehicle", new { id="vehicleForm" }))
{
  <div id="vehicle-editor">
  //very hacky, I normally return json with embedded html
  @Html.HiddenFor(m => m.Action)
  @Html.EditorFor(m => m.Vehicle)
  </div>
}

您会注意到编辑器为 Car 而不仅仅是 Vehicle 创建 html 输入。您可以利用这一点。

我会将 EditorFor 包装在一个 html 元素(例如 div)中,当下拉菜单发生变化时,Ajax 会调用为另一个车辆 html 片段提取部分内容(比如使用 jQuery)。至于回帖,我也会在同一个 javascript/jquery 事件中为下拉,更改表单的操作。

请注意,这只是一个原型/spike,我实际上不会这样写。

【讨论】:

  • 这是我想要的更好地使用多态性,谢谢。但是为什么要制作 AddTruckModel 和 AddCarModel 呢?为什么不只是通过汽车和卡车?
  • 生成 Html 时,它会为 html 输入名称(如 Vehicle.Model)创建前缀,如果模型不匹配,这些名称在回发时将无法正确绑定。
猜你喜欢
  • 2021-04-11
  • 1970-01-01
  • 1970-01-01
  • 2013-03-06
  • 2020-01-17
  • 2016-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多