1

通常、EditorForModel を使用すると複合型がレンダリングされないことは承知していますが、チェックを行わず、複合型を含むすべてのプロパティに対して Html.Editor を呼び出すカスタム オブジェクト テンプレートを使用しています。

残念ながら、オブジェクト テンプレート内のプロパティの正しい TemplateHint 値を確認できますが、Editor 呼び出しはそれを使用していないようで、代わりに組み込みのコレクション テンプレートが使用されます。

私のオブジェクトテンプレートは基本的にこれです:

@foreach (var property in ViewData.ModelMetadata.Properties.Where(x => x.ShowForEdit))
{
  @Html.Editor(property.PropertyName)
}

名前を Editor 呼び出しに渡してテンプレートの使用を強制すると、テンプレートの ModelMetadata は空になります。

これはバグですか / 回避策はありますか?

いくつかの詳細情報:

したがって、私のビューモデルには次のものが含まれています。

[ACustomAttribute("Something")]
public IEnumerable<int> SelectedOptions { get; set; }

この属性は IMetadataAware を実装し、ModelMetadata の AdditionalValues コレクションにいくつかのものを追加し、TemplateHint を設定します。オブジェクト テンプレートからこのデータを読み取ることはできますが、カスタム テンプレートからは読み取れません。

4

1 に答える 1

2
@foreach (var property in ViewData.ModelMetadata.Properties.Where(x => x.ShowForEdit))
{
    if (!string.IsNullOrEmpty(property.TemplateHint))
    {
        @Html.Editor(property.PropertyName, property.TemplateHint)
    }
    else
    {
        @Html.Editor(property.PropertyName)
    }
}

~/Views/Shared/EditorTemplates/NameOfTheTypeOfCollectionElements.cshtmlただし、複雑なコレクション型 (別名)のテンプレートを解決するための確立された規則に依存せずUIHint、コレクション プロパティでを使用している場合は、次の点に注意してください。

[UIHint("FooBar")]
public IEnumerable<FooViewModel> Foos { get; set; }

その場合、~/Views/Shared/EditorTemplates/FooBar.cshtmlエディター テンプレートは に厳密に型指定する必要がありIEnumerable<FooViewModel>、 ではありませんFooViewModel。したがって、これがあなたのケースである場合、コレクションの個々のアイテムにアクセスしたい場合は、このカスタム テンプレート内でループするかどうかはあなた次第です。自動的にループして各要素のエディター テンプレートを呼び出す ASP.NET MVC ではなくなります。


アップデート:

問題を再現できません。

カスタム属性:

public class ACustomAttribute : Attribute, IMetadataAware
{
    private readonly string _templateHint;
    public ACustomAttribute(string templateHint)
    {
        _templateHint = templateHint;
    }

    public void OnMetadataCreated(ModelMetadata metadata)
    {
        metadata.AdditionalValues["foo"] = "bar";
        metadata.TemplateHint = _templateHint;
    }
}

モデル:

public class MyViewModel
{
    [ACustom("Something")]
    public IEnumerable<int> Foos { get; set; }
}

コントローラ:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var model = new MyViewModel
        {
            Foos = Enumerable.Range(1, 5)
        };
        return View(model);
    }
}

ビュー ( ~/Views/Home/Index.cshtml):

@model MyViewModel

@using (Html.BeginForm())
{
    @Html.EditorForModel()
}

オブジェクト タイプのエディタ テンプレート ( ~/Views/Shared/EditorTemplates/Object.cshtml):

@foreach (var property in ViewData.ModelMetadata.Properties.Where(x => x.ShowForEdit))
{
    if (!string.IsNullOrEmpty(property.TemplateHint))
    {
        @Html.Editor(property.PropertyName, property.TemplateHint)
    }
    else
    {
        @Html.Editor(property.PropertyName)
    }
}

カスタム エディター テンプレート ( ~/Views/Shared/EditorTemplates/Something.cshtml):

@model IEnumerable<int>

<h3>
    @ViewData.ModelMetadata.AdditionalValues["foo"]
</h3>

@foreach (var item in Model)
{
    <div>
        @item
    </div>
}

結果:

ここに画像の説明を入力

ご覧のとおり、追加した追加のメタデータがテンプレートに表示されています。

于 2012-08-10T12:34:57.867 に答える