私は MVC3 アプリケーションを開発しており、ユーザーがドキュメントのメタ情報を編集できるページ (まあ、ビュー) を持っています (古典的な@Html.BeginForm
使用法)。一般的なドキュメントの場合、入力する標準フィールドがユーザーに表示されますが、ドロップダウン リストを介してドキュメントのタイプを指定できます。これは、ajax 呼び出しを介して、edit-document-form に新しいフィールドをロードします。ユーザーが完成したフォームを送信すると、最後に、コントローラーはすべての標準フィールドに加えて、選択されたドキュメントのタイプに固有として読み込まれたすべてのフィールドを読み取る必要があります。
質問は、コントローラーでこの余分なフィールドをすべて処理するにはどうすればよいですか? class と、、などDocument
のその他のクラス extendsinf があり、それぞれが特定のプロパティ (およびフォームにロードされるこのフィールド) を持っているとします。コントローラーにアクションを記述するにはどうすればよいでしょうか?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;
}
}
しかし、それは私には非常に汚いアプローチのようです。これを達成する方法について、より良いアイデアはありますか?このようなシナリオにアプローチするには、私が何も知らないパターンがあるのかもしれません。
アップデート
2番目のアイデアが頭に浮かびます。Document
ロブ・ケントの答えにコメントした後、次のようなプロパティを持つクラスを1つだけ持つ、別のアプローチを取ることができると思いました
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
がおそらく実行時に生成されることを考えると、この 2 番目のアプローチを好むでしょうか?