2

MVC でフォームを作成し、[ControlType]For([expression])ヘルパー メソッド (EG Html.TextBoxFor(...))を使用しています。

データをコントロールにバインドするには、次の ViewModel を使用しています。

public class UserViewModel
{
    //The Model that will be used to bind data to the elements
    public UserModel User { get; set; }

    //Used to bind selectable options to DropDownLists
    public SelectList DescentTypes { get; set; }
    public SelectList GenderTypes { get; set; }
}

これを使用すると、コントロールの名前がname="Property.SubProperty"(EG name="User.Id")に設定されますname="Id"が、HTML フォームのように表示したいと思います。

フレームワークがそれを ViewModel (UserViewModel) または単に Model (User) 自体に変換できるように、多くのカスタム コードを記述する必要なくこれを行うことは可能ですか?

4

1 に答える 1

1

変更する非常に正当な理由がない限り、デフォルトの名前をそのままにしておくことをお勧めします。ID(あなたの質問が傾いているように見えます)はより柔軟です。

IDの変更

ID はフォームで送信されないため、モデル バインディングを壊さずに必要に応じて設定できます。デフォルトでは、それらは階層的ですが、インラインで上書きできます:

@Html.TextBoxFor( o => o.UserName, new { id = "foo" } )

もちろん手作業です。

大きな懸念が外部の JS/CSS である場合data-*は、ID ではなく (CSS/jQuery などの) セレクターでクラス名と属性を使用することをお勧めします。

@Html.TextBoxFor( o => o.User.UserName, new { data_role="grand-total" } )

これはまだ手動ですが、説明的であり、ID から独立しています。

ビューでスクリプトのスニペットを使用して、ビュー内で直接最も簡単に利用できるデータでより大きな JS クラスを初期化することがあります。これにより、動的な値を使用して初期化できるようにしながら、スクリプトの大部分を外部ファイルに置くことができます。これは、ID 以外にも役立ちます。

生成されたマークアップとバインディングの変更

参考までに、IDと名前を変更したいとします。

  1. 独自のHtmlHelper拡張メソッドを記述して、必要なマークアップを作成します。おそらく、式をとらない既存のメソッドをラップし、それらに明示的な値を渡して、必要な名前を示すことができます。
  2. ModelBinder未加工のフォーム コレクションをマップする独自の記述を行います。
  3. 階層オブジェクトを処理するための戦略を決定します (これが、そもそも命名規則が存在する主な理由です)。

項目 #3 は、命名の実行方法とモデル バインディングのマッピング方法を示すプロパティを装飾することで対処できます。これはすぐに複雑になる可能性があります。

public class UserViewModel
{
    // use this metadata to determine how to handle properties on this member
    [Flatten]
    public UserModel User { get; set; }

    public SelectList DescentTypes { get; set; }
    public SelectList GenderTypes { get; set; }
}

代替案

  1. Userのプロパティを直接ビュー モデルに追加して、ビュー モデルをフラット化します。ドメイン モデルからビュー モデルを構成しているようです。これは通常、良い考えではありません。ドメインモデルに直接バインドすることの長所/短所を読むことをお勧めします。

  2. ネーミングはお任せください。それは本当に何も傷つけず、生活を楽にします。ヘルパー メソッドを使用することで、クライアント コードで名前/ID を直接操作することを避けることができます。

例えば:

// JavaScript + Razor
var name = "@Html.NameFor( o => o.User.Id )";
alert(name);
于 2013-09-04T20:21:44.803 に答える