我正在开发一个 MVC3 应用程序,并且我有一个页面(嗯,一个视图),可以让用户编辑文档的元信息(经典@Html.BeginForm
用法)。对于一般文档,用户将看到要填写的标准字段,但通过下拉列表,他们将能够指定文档的类型:这将通过 ajax 调用在 edit-document-form 上加载新字段。当用户提交完整的表单时,最后,控制器应该读取所有标准字段,加上所有加载的特定于所选文档类型的字段。
问题是,如何处理控制器中的所有这些额外字段?假设我有Document
class 和一堆其他类 extendinf Document
,比如Contract : Document
,Invoice : Document
等等Complaint : Document
,每个都有特定的属性(并且这个字段加载到表单上),我如何在控制器中编写动作?
我想使用类似的东西(为简洁起见,我将省略所有转换、验证等)
[HttpPost]
public ActionResult Save(dynamic doc)
{
int docType = doc.type;
switch (docType)
{
case 1:
var invoice = new Invoice(doc);
invoice.amount = Request.Form["amount_field"];
invoice.code = Request.Form["code_field"];
//and so forth for every specific property of Invoice
Repository.Save(invoice);
break;
case 2:
var contract = new Contract(doc);
contract.fromDate = Request.Form["fromDate_field"];
contract.toDate = Request.Form["toDate_field"];
//and so forth for every specific property of Contract
Repository.Save(contract);
break;
..... // and so forth for any document types
default:
break;
}
}
但这对我来说似乎是一种非常肮脏的方法。您对如何实现这一目标有更好的想法吗?也许有一种我对处理这种情况一无所知的模式。
更新
我想到了第二个想法。在评论了 Rob Kent 的回答后,我想我可以采取不同的方法,只有一个类Document
具有类似的属性
public IEnumerable<Field> Tipologie { get; set; }
在哪里
public class Field
{
public int IdField { get; set; }
public String Label { get; set; }
public String Value { get; set; }
public FieldType ValueType { get; set; }
public List<String> PossibleValues { get; set; } // needed for ENUMERATION type
}
public enum FieldType
{
STRING, INT, DECIMAL, DATE, ENUMERATION
}
这是更好的方法吗?在这种情况下,我可以只有一个动作方法,比如
[HttpPost]
public ActionResult Save(Document doc)
但是我应该在视图中创建字段以使 MVC 引擎将绑定返回到模型吗?鉴于从Document
第一种方法继承的类可能会在运行时生成,您更喜欢第二种方法吗?