2

一方が他方から派生した2つのクラスがあるとしましょう。

動物と犬

public class Animal
{
    public String Name { get; set; }
}

public class Dog : Animal
{
    public Boolean HasSpots { get; set; }
}

私のコントローラーでは、動物をインデックスビューに渡します

public ActionResult Index()
{
    return View(new Dog() {Name = "Dog"});
}

インデックス-犬を連れて行くエディターテンプレートに渡された動物をキャストしました。

@model MvcApplication1.Models.Animal

@using (Html.BeginForm("About", "Home", FormMethod.Post, null))
{
    @Html.EditorFor(x =>  x, "Dog", "Animal")

    <input type="submit" value="Begin" />
}

これは正常に機能しますが、コントローラーでDogに明示的にキャストバックしようとすると、Aboutに投稿してもキャストされません。カスタムモデルバインダーを作成する必要があると想像しますが、その方法がわかりません。または、何かが完全に欠けている場合。インターフェイスを含めずにこれを回避する方法。

(これを小さなテスト例として使用すると、実際のクラスはもう少し複雑になります)

4

1 に答える 1

5

デフォルトのモデルバインダーは、予想よりも多くの派生クラスを投稿しているかどうかを推測しようとはしません。したがって、フォームに、より派生したクラスのフィールドがある場合でも、アクションがクラスの動物を期待している場合、犬は作成されなかったため、動物が作成され、犬にキャス​​トすることはできません。

ここであなたを助けるためのインターフェースの方法がわかりません。アクションにインターフェイスまたは抽象クラスを受け入れさせると、デフォルトのモデルバインダーは、前述の型をインスタンス化できないため、例外をスローします。

カスタムモデルバインダーは、この状況に対処できます。私が見たすべてのアプローチは、いくつかの追加のメタデータをミックスに取り込むことを含みます。

追加のフォームフィールドを使用して実際のタイプを保持する例は、次のとおりです。 List<BaseClass>とエディターテンプレートを使用したViewModel

属性を使用して一種の「既知のタイプ」を実行する例は、次のとおりです。http://mvccontrib.codeplex.com/wikipage?title=DerivedTypeModelBinder&referringTitle=Documentation

于 2012-11-18T21:14:16.910 に答える