在c# MVC 4/5中绑定任何字段前缀到动作参数

本文关键字:前缀 字段 参数 任何 绑定 MVC | 更新日期: 2023-09-27 18:13:14

我使用c# ASP。. Net MVC 4和MVC 5.

我使用一个聚合模型VmVehicleGroup,它看起来有点像:

public class VmVehicleGroup {
    public VehicleTypeEnum Type { get; set; }
    public List<VmVehicle> Vehicles { get; set; }
    public VmVehicle Editable { get; set;}
}

主视图有每个组的部分,例如

@Html.Partial(x => x.Cars, "_VehicleEditor")
@Html.Partial(x => x.Bus, "_VehicleEditor")
@Html.Partial(x => x.Truck, "_VehicleEditor")

每组部分显示Model.Vehicles,并给出Model.Editable的编辑器模板

我的问题来自于ModelState。每个部分都将为Model.Editable呈现相同的输入字段名/id。当存在ModelState验证错误时,例如'Car'部分的验证错误将出现在所有其他表单上,而不仅仅是Car。我通过在编辑器部分中为模型添加前缀来解决这个问题,例如:

ViewData.TemplateInfo.HtmlFieldPrefix = Model.Type.ToString(); // VehicleTypeEnum

添加/编辑表单现在将提交Model.Editable与字段post数据前缀,即:Car。Reg,车。的名字,车。型号和车牌号我的问题出现在MVC动作。我的操作现在看起来像这样:

[ValidateAntiForgeryToken]
[AcceptVerbs(HttpVerbs.Post)]
[Route("Edit", Name = "EditVehicle")]
public ActionResult Edit([Bind(Prefix = "Car")] VmVehicle car, [Bind(Prefix = "Bus")] VmVehicle bus, [Bind(Prefix = "Truck")] VmVehicle truck, ....)
{
    var model = car ?? bus ?? truck;
    ...
}

我的问题是,这是维护的噩梦——对于每个VehicleTypeEnum,我需要添加额外的绑定参数。我不能为带前缀的模型设置单个动作。

我试过使用public ActionResult Edit(VmVehicle model) {},但前缀阻碍了MVC绑定。不幸的是,MVC似乎也不让你绑定一个通配符或命令分隔前缀,即:*。汽车或汽车,公共汽车,卡车。

是否有可能鼓励MVC动作接受任何前缀,同时为ModelState验证错误保留前缀?

在c# MVC 4/5中绑定任何字段前缀到动作参数

我看到在您的视图中,针对不同类型的车辆有不同的部分。这意味着你事先知道有哪些不同的车辆类型。

正如您之前所知道的,您只需要在创建视图模型时对组进行分离。例如,创建一个包含汽车、卡车、公共汽车等不同列表的视图模型。通过这种方式,您将在客户端拥有所需的前缀。

post action呢?好吧,而不是接收列表作为单独的参数,只是接收一个类类似于你用来渲染编辑器,即

使用具有以下属性的类来创建编辑器(将其用作视图模型):

public class VehiclesViewModel
{
  public List<Vehicle> Cars { get; set;}
  public List<Vehicle> Buses { get; set;}
  // other stuff here!
}

如果你使用像这样的类,它也有汽车,公交车等列表,数据将被自动绑定,即,而不是使用:

public ActionResult Edit([Bind(Prefix = "Car")] VmVehicle car, 
     [Bind(Prefix = "Bus")] VmVehicle bus, ...)

使用如下动作:

public ActionResult Edit(VehiclesViewModel vehicles)

和模型绑定器将为您处理前缀,并将每辆车绑定到相应的列表。

显示和编辑模板

但是,如果您为每种类型的车辆使用不同的类,您可以使用自定义的显示和编辑模板,这可以使您的工作更轻松。也就是说,你可以定义显示和编辑适用于给定数据类型的模板。所以,如果你对每种车辆都有不同的类,你可以为每个不同的类使用显示和编辑模板,并使用' DisplayFor '或EditorFor,你会自动获得所需的视图。以下链接中的一些示例:

    在ASP中探索显示和编辑器模板净MVC3/4
  • ASP。. NET MVC显示模板和编辑模板用于实体框架DbGeography空间类型
  • ASP。. NET MVC显示和编辑器模板

(我不明白你到底在做什么,所以我可以给出一个更具体的解释)

模型绑定复杂对象列表

人们发现MVC的另一个经典问题是,当他们想要绑定一个必须编辑的复杂对象列表时,他们不知道如何做到这一点,以便他们在post action中获得对象列表。

Phil Haack的解释是你能找到的最好的解释之一。