26

ViewDataDictionary1行のコードでモデルと追加のプロパティを使用して を作成する方法はありますか? RenderPartial複数行にわたって ViewDataDictionary を明示的にアセンブルせずに、モデルといくつかの追加の表示構成プロパティの両方をアセンブルしながら、厳密に型指定されたビューを呼び出そうとしています。RenderPartialモデルobjectと a の両方を使用するオーバーロードを考えると、それは可能であるように思われますが、両方ViewDataDictionaryが設定されている場合は単に を無視するように見えViewDataDictionaryます。

// FAIL: This will result in ViewData being a ViewDataDictionary
// where Model = MyModelObject and there are no other parameters available.
this.Html.RenderPartial("SomePartialView", MyModelObject, new ViewDataDictionary(new { SomeDisplayParameter = true }));

同じ問題を抱えている他の人を見つけましたが、彼らの解決策は、私が見つけたのと同じ複数行の概念です。ViewDataDictionaryモデルで離散を作成し、新しいパラメーターを追加して、RenderPartial呼び出しで使用します。

var SomeViewData = new ViewDataDictionary(MyModelObject);
SomeViewData.Add("SomeDisplayParameter", true);
this.Html.RenderPartial("SomePartialView", SomeViewData);

ChainedAdd新しい要素が追加された重複した辞書を返すメソッドにそのロジックをいつでもラップできますが、ViewDataDictionaryこれを行う を作成する方法が欠けているようです (そして、それは私が望んでいたよりも少し多くのオーバーヘッドです)為に)。

this.Html.RenderPartial("SomePartialView", new ViewDataDictionary(MyModelObject).ChainedAdd("SomeDisplayParameter", true));

public static ViewDataDictionaryExtensions {
    public static ViewDataDictionary ChainedAdd(this ViewDataDictionary source, string key, object value) {
        return source.ChainedAdd(new KeyValuePair<string,object>(key, value));
    }
    public static ViewDataDictionary ChainedAdd(this ViewDataDictionary source, KeyValuePair<string, object> keyAndValue) {
        ViewDataDictionary NewDictionary = new ViewDataDictionary(source);
        NewDictionary.Add(keyAndValue);
        return NewDictionary;
    }
}

同様に、ModelState が読み取り専用であるためViewDataDictionary、明示的ModelModelState単純にアセンブルしようとすると、コンパイル エラーが発生します。

// FAIL: Compilation error
this.Html.RenderPartial("SomePartialView", new ViewDataDictionary { Model = MyModelObject, ModelState = new ViewDataDictionary( new { SomeDisplayParameter = true }});

ANSWER(S): Craig と私は、仕事を成し遂げる 2 つの別々の構文を見つけたようです。この場合、私は間違いなく偏っていますが、最初にモデルを設定してから「装飾」するというアイデアが好きです。

new ViewDataDictionary(MyModelObject) { { "SomeDisplayParameter", true }, { "SomeOtherParameter", 3 }, { "SomeThirdParameter", "red" } };

new ViewDataDictionary(new ViewDataDictionary() { {"SomeDisplayParameter", true }})
    { Model = MyModelObject };

もちろん、彼の[最終的には的確な]回答がなければ、私はまだ車輪を回転させているので、円は四角になります.

4

5 に答える 5

2

HtmlHelper の拡張メソッドを作成して、プロパティ名と値を匿名オブジェクトから ViewDataDictionary にコピーしました。

サンプル

Html.RenderPartial("SomePartialView", MyModelObject, new { SomeDisplayParameter = true })

HtmlHelper 拡張機能

public static void RenderPartial(this HtmlHelper htmlHelper, string partialViewName, object model, object viewData)
{
    var vdd = new ViewDataDictionary(model);
    foreach (var property in viewData.GetType().GetProperties()) {
        vdd[property.Name] = property.GetValue(viewData);
    }
    htmlHelper.RenderPartial(partialViewName, vdd);
}
于 2014-06-26T21:59:21.447 に答える
1

これは、古いスタイルのmvc aspxビューで私にとってうまくいったものです:

<% Html.RenderPartial("ContactPartial", Model.ContactFactuur, new ViewDataDictionary(this.ViewData ) { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "Factuur" } }); %>

ここでのことは、コンストラクターで、検証メッセージに必要なモデル状態を含むビューデータディクショナリーである現在のビューデータ「new ViewDataDictionary(this.ViewData)」を使用することです。

于 2014-11-22T15:42:31.953 に答える
0

まったく同じ質問でここに来ました。

私がうまくいくと思ったのはこれでした(VB Razor構文を許してください)

 @Code Html.RenderPartial("Address", Model.MailingAddress, New ViewDataDictionary(New With {.AddressType = "Mailing Address"}))End Code

しかしもちろん、実行時に次のエラーが発生します。

System.InvalidOperationException がユーザー コードによって処理されませんでした

Message=ディクショナリに渡されたモデル アイテムのタイプは 'VB$AnonymousType_1`1[System.String]' ですが、このディクショナリにはタイプ 'ViewModel.Address' のモデル アイテムが必要です。

しかし、私が見つけたのは、とにかく使用したかったのは Editor Template だったということです。

RenderPartial を使用する代わりに:

@Html.EditorFor(Function(model) model.MailingAddress, "Address",  New With {.AddressType = "Mailing Address"})

エディター テンプレートは、生きている部分的なビューにすぎません

~/Views/{モデル|共有}/EditorTemplates/templatename.vbhtml

Address のテンプレートは厳密に型指定された部分ビューですが、EditorFor メソッドを使用すると、anon オブジェクトを使用してビュー データ項目を簡単に追加できます。

上記の例では、テンプレート名「Address」を含める必要はありませんでした。これは、MVC がモデル タイプと同じ名前のテンプレートを検索するためです。

同じ方法で表示テンプレートをオーバーライドすることもできます。

于 2012-10-20T20:17:39.743 に答える