質問

私はMVCが初めてですが、これまでずっと、すべてのドキュメント、すべての質問、見つけることができるすべてのブログ投稿を読み、私がしていることはすべて車軸に完全に包まれています。

<!> quot; create <!> quot;を作成しようとしています。アクションとビュー。私のデータ入力は比較的単純で、一般的です。ドロップダウンリストとテキストボックスがあります。私の場合、ユーザーの連絡先チャネルを作成しています。ドロップダウンボックスでメールとtextmsgを選択し、テキストボックスに関連する連絡先情報(整形式のメールアドレスまたは携帯電話番号)を入力します。

ここに(少し簡略化した)ビューページがあります:

 <tr>
     <td><%= Html.DropDownList("ChannelDescription", Model.ChannelDescription, "Select a Channel", new { id = "ChannelDDL", onchange="ChannelDDLChanged()" })%>
         <br />
         <%= Html.ValidationMessage("ChannelDescription", "Please Select a Channel") %>
      </td>
      <td>
           <%= Html.TextBox("SubscriberNotificationAddr") %> <br />
           <%= Html.ValidationMessage("SubscriberNotificationAddr", "Please enter a contact address or number") %>
       </td>
  </tr>

ViewDataDictionaryを使用するのではなく、厳密に型指定されたViewDataモデルを使用しています。 ChannelDescription要素はSelectListであり、選択リストで選択なしで初期化されます。

フォームの最初の表示、フォームへのデータ入力、およびコントローラーによるフォームからのデータの抽出は問題ありません。

私の問題は、データに不正な形式の電子メールアドレスや携帯電話番号などのエラーが含まれ、ビューに戻る必要がある場合、ドロップダウンリストの選択を再表示することに成功しなかったことです。 ChannelDescription要素は、選択されたアイテムとしてユーザーが選択したコントローラーで再作成されます。ビューのその行にブレークポイントを設定し、アイテムのリストの選択した要素のSelectedプロパティがtrueに設定されていることを確認しましたが、デフォルトの<!> quot; Select a Channel <!> quot;が表示されたままです。

これは非常に一般的な状況のように思われるので、それほど難しいことではありません。私は何を間違えていますか?

FYI、これはMVC 1.0(リリース)、Windows 7、VS 2008で、Firefox 3.5.2で実行されています。

役に立ちましたか?

解決 2

MVCチームのブラッドウィルソンと話し合い、DropDownListヘルパーメソッドの使用方法を誤解していると説明してくれました(私が読んだことから、かなり一般的だと思う誤解)。

基本的に、ViewModelの名前付きパラメーターでSelectListを指定し、適切なアイテムを選択してドロップダウンリストを作成するか、SelectListを別のパラメーターとして指定して、 ViewModelは、選択されたアイテムの単なる値文字列です。 SelectListパラメーターを指定すると、名前付き値はSelectListではなく、文字列または文字列のリストであると想定されます。

したがって、ViewModelには、ビューの1つの概念項目(ドロップダウンリスト)に2つの要素が含まれるようになります。したがって、次のようなモデルがあるかもしれません

string SelectedValue {get; set;}
SelectList DropDownElements { get; set;}

その後、DropDownElementsに選択肢を事前に入力できますが、モデルビューバインディングでは、SelectedValue要素を処理するだけです。そのようにすると、私にとってはかなりうまくいくようです。

他のヒント

上記の回答を見た後、私はそれをチェックアウトしたかったのです。なぜなら、私が見たすべての例は、厳密に型指定されたViewDataModelではなくViewDataDictionaryを実際に使用していたからです。

だから私はいくつかの実験をしました。プレーンなViewDataDictionaryを使用する非常にシンプルなビューを作成し、名前付きキーで値を渡しました。選択したアイテムは問題なく持続しました。次に、そのビュー(およびコントローラー)を別のビューにカットアンドペーストし、厳密に型指定されたViewDataモデルに切り替えるために必要なものだけを変更しました。また、選択されたアイテムが永続化されます。

では、単純なテストとアプリケーションで他に何が違いましたか?私のテストでは、単に<!> quot; Html.DropDownList(<!> quot; name <!> quot ;, <!> quot; optionLabel <!> quot;)<!> quot;を使用しました。しかし、私のアプリケーションでは、HTML属性を追加する必要があり、HtmlAttributesを含む利用可能なオーバーロードにはselectリストも含まれています。

選択リストパラメータを使用したDropDownListオーバーロードが壊れていることがわかりました!ダウンロードしたMVCソースコードを見ると、DropDownListが名前だけ、または名前とoptionLabelで呼び出されると、最終的にViewDataからターゲット選択リストを取得し、次の呼び出しでプライベートSelectInternalメソッドを呼び出します。

    return SelectInternal(htmlHelper, optionLabel, name, selectList, true /* usedViewData */, false /* allowMultiple */, (IDictionary<string, object>)null /* htmlAttributes */);

ただし、selectListパラメーターを指定して呼び出すと、次のようになります。

   return SelectInternal(htmlHelper, optionLabel, name, selectList, false /* usedViewData */, false /* allowMultiple */, htmlAttributes);

違いは、最初の(正常に機能する)で<!> quot; usedViewData <!> quot;パラメーターはtrueですが、2番目のパラメーターではfalseです。これは実際には問題ありませんが、SelectInternalルーチンに内部的な欠陥があります。

usedViewDataがfalseの場合、オブジェクト変数<!> quot; defaultValue <!> quot;を取得します。 ViewDataモデルから。 ただし、実際にはViewDataから返されるものがSelectListである場合、defaultValueは文字列または文字列の配列のように使用されます。 (IEnumerable<SelectListItem>)。

usedViewDataがtrueの場合、defaultValueはnullまたは文字列になります。

次に、defaultValueがnullでない場合、最終的にこれを含むコードブロックに入ります:

        foreach (SelectListItem item in selectList) {
            item.Selected = (item.Value != null) ? selectedValues.Contains(item.Value) : selectedValues.Contains(item.Text);
            newSelectList.Add(item);

selectListは渡された元のselectListであるため、アイテムはSelectListItem(string Text、string Value、bool Selected)です。ただし、selectedValuesはdefaultValueから派生し、文字列のリストではなくSelectListsのリストになります。そのため、各アイテムに対して、selectedValuesリストが<!> quot; Contains <!> quot;であるかどうかに基づいてSelectedフラグを設定しています。 item.Value。さて、SelectListsのリストは<!> quot; Contain <!> quot;にはなりません。文字列。したがって、item.Selectedは設定されません。 (訂正:実際、デバッガーでさらにトレースした後、selectedValuesは<!> quot; ToString()<!> quot;呼び出しによってdefaultValueから派生していることがわかりました。したがって、実際には文字列のリストですが、必要な値を含む<!> quot; System.Web.Mvc.SelectList <!> quot;-<!> quot; ToString()<!> quot;をSelectListのような複雑なオブジェクトに適用した結果結果は同じままです-そのリストで探している値を見つけることはできません。)

次に、新しく構築された<!> quot; newSelectList <!> quotを置き換えます。元の<!> quot; selectList <!> quot;に対して、それからHTMLの構築に進みます。

上記のように、カグダス(あなたの名前を殺したことを謝罪しますが、USキーボードでそれらの文字を作成する方法がわかりません)として、DropDownListの代わりに使用する独自のメソッドを作成する必要があると思いますHtmlHelper。このリリース1とリリース2はベータ2であるため、自分で正しく修正しない限り、バグの修正は期待できないでしょうか。

ところで、これまで私をフォローしてきた場合、このコードはsrc \ SystemWebMvc \ Mvc \ Html \ SelectExtensions.csの116-136行目付近にあります

はい、私もDropDownListを取得して、選択したアイテムを尊重するのに非常に多くの問題がありました。

myを確認してくださいこの質問に答えてください。覚えている限りでは、それが私がそれを機能させることができる唯一の方法でした。 ViewDataを介してリストを渡すことにより。

FYI、そのHtmlHelperメソッドの使用を停止しました。ループを使用して<select>および<option>タグを自分で出力し、自分でチェックしてselectedタグのoptionプロパティを設定するだけです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top