3

表示テンプレートと、インターフェイスおよびインターフェイスを実装するオブジェクトの処理に問題があります。この例では、固定された方法でレンダリングしたい多くのオブジェクトがあり、インターフェイスを作成し、共有表示テンプレート フォルダーに配置することにしたビューでこれを参照することにしました。 DisplayForビューにインターフェイスを実装する渡されたオブジェクトに対して機能するように縫い目がありません。これに対する解決策を知っている人はいますか。

おそらくコードで説明する方が簡単なので、簡単な例を書きました。基本インターフェースとそれを継承する 2 つのクラス:

public interface IPet
{
    String Name { get; }
}

public class Dog : IPet
{
    public String Name { get; set; }
}

public class Cat : IPet
{
    public String Name { get; set; }
}

共有表示テンプレートの表示テンプレートの例

@model IPet

<div>@Model.Name</div>

ビューに渡されるビューモデルの例

public class VM
{
    public IPet Master { get; set; }
    public IEnumerable<IPet> Minions { get; set; }
}

コントローラー (この場合はモック情報を作成するため)

    public ActionResult Index()
    {
        var viewModel = new VM();
        viewModel.Master = new Cat(){Name = "Fluffy"};

        var minions = new List<IPet>();

        minions.Add(new Dog(){Name = "Dave"});
        minions.Add(new Dog(){Name = "Pete"});
        minions.Add(new Cat(){Name = "Alice"});

        viewModel.Minions = minions;

        return View(viewModel);
    }

そして最後に、私が期待するDisplayForビュー

@model ViewInheritance.Models.VM

<h2>Master</h2>

@Html.DisplayFor(x => x.Master)

<h2>Minions</h2>

@Html.DisplayFor(x => x.Minions)

すべてのオブジェクトがビュー モデルでインターフェイスとして定義されている場合、表示テンプレートを使用できないのはなぜですか?

私が見つけた1つの解決策は、単にコードを使用することです

@Html.DisplayFor(x => x.Master, "IPet")

要約すると、質問は次のとおりです。

なぜこれが起こるのですか?どのタイプの実装が実際に共通の共有ビューを見ているべきかをDisplayFor正しく理解する方法はありますか?CatIPetIPet.cshtml

ありがとう

4

2 に答える 2

0

新しい MVC アプリケーションを開始し、実際にビューをコンパイルするようにコードを修正すると、正常にレンダリングされます。ビューを共有フォルダーに移動するときにも正常にレンダリングされます。

私はセッターをIPetに追加しました:

public interface IPet
{
    String Name { get; set; }
}

実装を更新し、パブリック アクセサーを追加しました。

public class Dog : IPet
{
    public String Name { get; set; }
}

public class Cat : IPet
{
    public String Name { get; set; }
}

私はあなたの VM をそのままにし、ビューのコードも変更しませんでした。F5 を押して MVC アプリケーションを実行すると、期待どおりの結果が表示されました (画像を参照)。ここに画像の説明を入力

于 2012-02-03T12:02:04.590 に答える
-1

残念ながら、ASP.NET MVC は現在、実装されたインターフェイスに基づくテンプレートの自動選択をサポートしていないと思います。クラスは複数のインターフェイスを実装できるため、これは理にかなっていると思います。これらのインターフェイスの複数のテンプレートがある場合、フレームワークはどれを選択する必要がありますか?

設計が対応できる場合は、インターフェイスの代わりに基本クラスを使用できます。

  • IPet(おそらく抽象) に変更しclassます。
  • に変更IPet.cshtmlPet.cshtmlます。

それ以外の場合は、使用するテンプレートをフレームワークに明示的に伝える必要があると思います。以下にいくつかのオプションを示します。

  • ビュー モデル プロパティを で装飾します[UIHint]
  • HtmlHelperなどのメソッドへの呼び出しでテンプレートを指定しますDisplayFor
  • 独自のものを作成し、結果のプロパティをModelMetadataProvider変更します。TemplateHintModelMetadata
于 2014-07-10T00:24:08.573 に答える