1. ホーム
  2. asp.net-mvc

[解決済み] ASP.NET MVC部分表示:入力名のプレフィックス

2022-08-04 20:35:54

質問

例えば、以下のようなViewModelがあるとします。

public class AnotherViewModel
{
   public string Name { get; set; }
}
public class MyViewModel
{
   public string Name { get; set; }
   public AnotherViewModel Child { get; set; }
   public AnotherViewModel Child2 { get; set; }
}

ビューの中で

<% Html.RenderPartial("AnotherViewModelControl", Model.Child) %>

パーシャルでは

<%= Html.TextBox("Name", Model.Name) %>
or
<%= Html.TextBoxFor(x => x.Name) %>

しかし、問題は、モデルバインダーが正しく動作するためには name="Child.Name" を持つ必要があるのに、両方とも name="Name" をレンダリングしてしまうことです。または、同じ部分ビューを使用して2番目のプロパティをレンダリングすると、name="Child2.Name"が表示されます。

部分ビューで必要な接頭辞を自動的に認識させるにはどうすればよいですか。パラメータとして渡すことはできますが、これはあまりにも不便です。たとえば、再帰的にレンダリングしたい場合、これはさらに悪いことです。部分ビューをプレフィックス付きでレンダリングする方法、あるいはさらに良い方法は、呼び出したラムダ式を自動的に再定義して

<% Html.RenderPartial("AnotherViewModelControl", Model.Child) %>

は、生成された名前/ID文字列に自動的に正しい"Child."接頭辞を追加しますか?

私は、3rd パーティーのビューエンジンおよびライブラリを含む、任意のソリューションを受け入れることができます - 私は実際に Spark View Engine (私はそのマクロを使用して問題を解決します) および MvcContrib を使用しますが、そこでソリューションを見つけられませんでした。XForms、InputBuilder、MVC v2 - この機能を提供する任意のツール/洞察は素晴らしいものになるでしょう。

現在、私はこれを自分でコーディングすることを考えていますが、それは時間の無駄のように思えます、このつまらないものがすでに実装されていないとは信じられません。

多くの手動ソリューションが存在する可能性があり、それらのすべてが歓迎されます。たとえば、私のパーシャルは IPartialViewModel<T> { public string Prefix; T Model; } に基づいていることを強制することができます。しかし、私はむしろいくつかの既存の/承認されたソリューションを好むでしょう。

UPDATE: 答えのない同様の質問があります。 はこちら .

どのように解決するのですか?

Htmlヘルパークラスは、このように拡張することができます。

using System.Web.Mvc.Html


 public static MvcHtmlString PartialFor<TModel, TProperty>(this HtmlHelper<TModel> helper, System.Linq.Expressions.Expression<Func<TModel, TProperty>> expression, string partialViewName)
    {
        string name = ExpressionHelper.GetExpressionText(expression);
        object model = ModelMetadata.FromLambdaExpression(expression, helper.ViewData).Model;
        var viewData = new ViewDataDictionary(helper.ViewData)
        {
            TemplateInfo = new System.Web.Mvc.TemplateInfo
            {
                HtmlFieldPrefix = name
            }
        };

        return helper.Partial(partialViewName, model, viewData);

    }

で、これをビューで次のように使用します。

<%= Html.PartialFor(model => model.Child, "_AnotherViewModelControl") %>

をクリックすると、すべてがうまくいっていることがわかるでしょう