【问题标题】:mvc3 composing page and form element dynamicallymvc3动态组合页面和表单元素
【发布时间】:2012-05-08 16:12:27
【问题描述】:

我正在开发一个 MVC3 应用程序,并且我有一个页面(嗯,一个视图),可以让用户编辑文档的元信息(经典的 @Html.BeginForm 用法)。对于一般文档,用户将看到要填写的标准字段,但通过下拉列表,他们将能够指定文档的类型:​​这将通过 ajax 调用在 edit-document-form 上加载新字段。 当用户提交完整的表单时,最后,控制器应该读取所​​有标准字段,以及加载的所有特定于所选文档类型的字段。

问题是,如何在控制器中处理所有这些额外的字段? 假设我有Document 类和一堆其他类扩展Document,如Contract : DocumentInvoice : DocumentComplaint : 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 继承的类可能会在运行时生成,您更喜欢第二种方法吗?

【问题讨论】:

  • 是的,这会起作用,因为您只是在创建一个属性包。它实际上是否可以帮助您区分 Document 的类型?你最终会得到一个松散类型的文档,但由于你在回复中说你不知道你有什么类型,这是你必须忍受的限制。

标签: asp.net-mvc-3


【解决方案1】:

为了在服务器上保持硬类型化,您可以使用带有自定义绑定器的抽象基类型。在此处查看我的答案以了解其工作原理:MVC generic ViewModel

这个想法是,每次他们加载一组新字段时,您将 Bi​​ndingType 表单变量更改为处理程序的实例化类型。自定义活页夹负责在提交时创建正确的类型,然后您可以在您的操作中对其进行评估,例如:

if (model is Contract) ...

我不确定你是否能够设置不同的动作,每个动作都有不同的签名,例如:

public ActionResult Save(Contract contract) ...
public ActionResult Save(Invoice invoice) ...

很确定这是行不通的,因为 Mvc 已经决定要调用哪个方法,或者它可能会先查看返回的类型,然后再决定。

在我的链接示例中,我正在检查被覆盖的基本成员,但如果这对您来说不是问题,您只需要创建正确的类型。

【讨论】:

  • 据我所知(我现在尝试过)m​​vc 不支持在同一个控制器上具有相同名称但不同签名的不同操作,除非您指定不同的 Http 方法。此外,在实际应用程序中,我不知道会从Document 派生哪些类以及有多少类:所有这些类都将在运行时根据数据库上的值动态创建和编译。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-24
  • 1970-01-01
  • 2018-01-07
  • 1970-01-01
  • 2016-12-19
  • 1970-01-01
相关资源
最近更新 更多