0

私のインターフェイスには、次のようなテキストボックスのリストがあります: http ://screencast.com/t/YjIxNjUyNmU

各テキストボックスはテンプレートに関連付けられているため、テキストボックスの数は不明です。私のページでは、これらのテンプレートのいくつかに番号を関連付けることが目標です。

以下にサンプルのHTMLコードを示します。

<%  // loop on the templates
    foreach(ITemplate template in templates)
    {
        // get the content from the input dictionary
        int val;
        content.TryGetValue(template.Id, out val);
        // convert it as a string
        string value = ((val > 0) ? val.ToString() : string.Empty);

        // compute the element name/id (for dictionary binding)
        string id = ??????????
        string name = ??????????????
%>
        <label for="<%= name %>"><%= template.Name %></label>
        <input type="text" id="<%= id %>" name="<%= name %>" value="<%= value %>" />
        <br />
<%  }
%>

私のコントローラーで期待しているのは、最初のintがテンプレートIDで、もう1つがユーザーによって指定されたカウントであるIDictionaryを取得することです。

これが私が欲しいものです:

public ActionResult Save(int? id, Dictionary<int, int> countByTemplate)

私はたくさんのことを試しましたが、何もうまくいきませんでした。ソースを読み込もうとしましたが、迷路であり、モデルのバインドに関する情報を取得しようとすると頭が痛くなります。

質問:

  • モデルバインディングがどのように機能するかについての優れたリソースはありますか?徹底的に説明したいのですが、特定の例について説明している84093043のブログにうんざりしています。
  • IDictionary(またはコントローラーのアクションでIDictionary)を取得するために使用してHTMLを作成するにはどうすればよいですか?

あなたの助けをどうもありがとう

4

2 に答える 2

1

配列、ディクショナリ、およびその他のコレクションにバインドするための入力要素を作成する方法については、http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspxを参照してください。

于 2010-05-25T18:45:44.010 に答える
1

わかりました...Leviのおかげで、私は解決策を得ることができました。よりクリーンなものではありませんが、機能します。

HTMLは次のように記述する必要があります。

<%
int counter = 0;
// loop on the templates
foreach(ITemplate template in templates)
{
        // get the value as text
        int val;
        content.TryGetValue(template.Id, out val);
        var value = ((val > 0) ? val.ToString() : string.Empty);

        // compute the element name (for dictionary binding)
        string id = "cbts_{0}".FormatMe(template.Id);
        string dictKey = "cbts[{0}].Key".FormatMe(counter);
        string dictValue = "cbts[{0}].Value".FormatMe(counter++);
%>
        <input type="hidden" name="<%= dictKey %>" value="<%= template.Id %>" />
        <input type="text" id="<%= id %>" name="<%= dictValue %>" value="<%= value %>" />
        <label for="<%= id %>"><%= template.Name %></label>
        <br />
<%  }
%>

値を格納するために非表示フィールドを追加する必要がありました。ASP.Net MVCが望む方法で辞書をループするために、「偽の」カウンターを導入しました。その結果、値とテキストボックスが空の場合は「0」で満たされた辞書を取得しました。

別の問題が発生しましたModelState。「値が必要」であるため、は無効と見なされました。値を必須にしたくないのですが、modelbinderコードを見ると、値が必須ではないことをバインダーに伝える方法が見つかりませんでした。

そこで、コントローラーをだましてModelState、次のようにすべてのエラーを削除しました。

public ActionResult Save(int? id, Dictionary<int, int> cbts)
{
    // clear all errors from the modelstate
    foreach(var value in this.ModelState.Values)
        value.Errors.Clear();

ええと...私は効果的に解決策を得ましたが、HTMLは今や醜く、直感に反しています(インデックスを使用してインデックスのないコレクションをループする??)。そして、この種のバインディングを使用するたびに、すべてを正しく機能させるためにトリックする必要があります。

そこで、辞書バインダーをより良いものにするために、新しい投稿を開きます。ASP.Net MVC2-辞書用のより優れたModelBinding<int、int>

編集-PavelChuchuvaのおかげで、よりクリーンなソリューションがあります。

コントローラコードでは、辞書の値としてnull許容整数を使用します。追加するコードはもう少しありますが、はるかにクリーンです。

public ActionResult Save(int? id, Dictionary<int, int?> cbts)
{
    // this is our final dictionary<int, int>
    Dictionary<int, int> cbtsFinal = new Dictionary<int, int>();
    // loop on the dicitonary with nullable values
    foreach(var key in cbts.Keys)
    {
        // if we have a value
        if(cbts[key].HasValue)
            // then put it in the final dictionary
            cbtsFinal.Add(key, cbts[key].Value);
    }
于 2010-05-26T08:20:49.383 に答える