Frage

Ich bin neu in MVC, aber ich habe schon überall hier, Lesen Sie alle Dokumente und alle Fragen und alle blog-posts, die ich finden kann, und alles, was ich Tue, ist, sich komplett eingewickelt um die Achse.

Ich bin versucht zu machen, eine "create" - Aktion und Ansicht.Meine Daten Einreise ist relativ unkompliziert, und gemeinsam:Ich habe ein drop-down-Liste und ein Textfeld.In meinem Fall, ich bin momentan dabei, einen Benutzer wenden-Kanal, und das Dropdown-Feld wählt zwischen E-Mail und textmsg, und das Textfeld wird dann in den entsprechenden Kontakt-Informationen, entweder eine wohlgeformte E-Mail-Adresse oder eine Handynummer.

Hier ist eine (leicht vereinfachte form) meine Ansicht-Seite:

 <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>

Ich bin mit einem stark typisierten ViewData-Modell, anstatt mit dem ViewDataDictionary.Der ChannelDescription element ist eine Auswahlliste, die initialisiert wird mit der Liste der Auswahlmöglichkeiten und keine Auswahl.

Die anfängliche Darstellung der form, die die Eingabe von Daten in die form, und die Extraktion der Daten aus dem Formular durch die Steuerung geht in Ordnung.

Mein problem ist, wenn die Daten einen Fehler enthält, wie eine mal-gebildet E-Mail-Adresse oder Handy-Nummer, und ich haben, um zurück zu der Ansicht, ich war nicht erfolgreich in immer die Dropdown-Liste Auswahl-neu angezeigt.Der ChannelDescription element ist neu in der controller mit der Benutzer hat die Wahl, wie das ausgewählte Element.Ich habe Haltepunkte an dieser Linie der Sicht, und überprüft haben, dass das ausgewählte element von der Liste der Elemente, die hat die Eigenschaft Selected auf true gesetzt, aber es zeigt immer noch der Standard "einen Kanal Auswählen".

Dies scheint, wie es wäre, eine sehr häufige situation, und sollte nicht so schwer sein.Was mache ich falsch?

FYI, dieses ist mit MVC 1.0 (Release), Windows 7 und VS 2008, unter Firefox 3.5.2.

War es hilfreich?

Lösung 2

hatte ich einige Gespräche mit Brad Wilson, von dem MVC-Team, und er erklärte mir, dass ich Missverständnis, wie die Dropdownlist-Helfer-Methode (ein Mißverständnis verwendet werden soll, dass ich denke, könnte ziemlich häufig sein, von dem, was ich gelesen habe ).

Im Grunde genommen, WEDER gibt ihm die Select in dem benannten Parameter des Ansichtsmodelles, und lassen Sie es die Dropdown-Liste aus, dass mit dem entsprechenden Artikel bauen, OR gibt ihm die Select als separate Parameter und lassen Sie die benannten Parameter der Ansichtsmodell sein nur der Wert Strings für das ausgewählte Element (s). Wenn Sie es ein Select Parameter geben, dann erwartet sie der benannten Wert ein String oder eine Liste von Zeichenketten zu sein, nicht ein Select.

So, jetzt Ihr Ansichtsmodell endet mit zwei Elementen für ein konzeptionelles Element in der Ansicht (die Dropdown-Liste). So könnten Sie ein Modell, das hat

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

Dann können Sie die DropDownElements mit den Entscheidungen vorab füllen, aber in Ihrer Modellansicht zu binden, müssen Sie nur mit SelectedValue Elemente beschäftigen. Es scheint für mich ziemlich gut zu funktionieren, wenn ich es auf diese Weise tun.

Andere Tipps

Nach der Anzeige der Antwort oben, ich wollte es überprüfen, da alle Beispiele, die ich gesehen hatte, hatte tatsächlich ViewDataDictionary, eher als eine stark typisierte ViewDataModel.

So habe ich einige Experimente.Ich konstruierte eine sehr einfache Ansicht, die mit einer einfachen ViewDataDictionary, und übergeben Werte von benannten Tasten.Sie hielt das ausgewählte Element just fine.Dann habe ich ausgeschnitten und eingefügt, die Sicht (und controller) auf einen anderen ein, und ändern Sie nur, was nötig war, zu wechseln, um eine stark typisierte ViewData-Modell.Lo und siehe, es auch beibehalten des ausgewählten Elements.

Also was war anders zwischen meine einfachen test und meine Anwendung?In meinem test hatte ich einfach "Html".DropDownList("name", "optionLabel")".Jedoch in meiner Anwendung habe ich gebraucht hatte, zum hinzufügen von HTML-Attributen, und die nur überladungen zur Verfügung, die im Lieferumfang enthalten HtmlAttributes gehören auch die select-Liste.

Es stellt sich heraus, dass die DropDownList-überlast mit einer select-Liste parameter ist pleite!Blick auf die heruntergeladene MVC-Quellcode, wenn DropDownList als nur ein name oder ein name und ein optionLabel, es endet abrufen der Ziel-wählen Sie Liste aus dem ViewData, und dann die Anrufung des privaten SelectInternal-Methode durch den folgenden Aufruf:

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

Jedoch, wenn es heißt mit einer Auswahlliste parameter, es endet mit den folgenden:

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

Der Unterschied ist, dass in der ersten (was funktioniert) der "usedViewData" - parameter true ist, während in dem zweiten, es ist falsch.Was ist eigentlich okay, aber macht ein interner defekt in der SelectInternal routine.

Wenn usedViewData false ist, wird eine Objekt-variable "defaultValue" aus der ViewData-Modell.Allerdings defaultValue verwendet wird, als ob es entweder ein string oder ein array von strings sein, wenn in der Tat das, was zurückgegeben wird, aus der ViewData ist eine Auswahlliste.(IEnumerable<SelectListItem>).

Wenn usedViewData wahr ist, dann defaultValue wird entweder null oder eine Zeichenfolge.

Dann, wenn defaultValue nicht null ist, landet es geht also in einen code-block, der enthält dies:

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

selectList ist das original selectList, die übergeben wurde, so wird das Element eine SelectListItem (string Text, string Value, und bool Selected).Aber selectedValues wurde abgeleitet von den defaultValue, und wird eine Liste von SelectLists, nicht eine Liste von strings.Also für jeden der Artikel, es ist Einstellung die Gewählte Flagge auf der Grundlage, ob die selectedValues Liste "Enthält" das Element.Wert.Gut, eine Liste von SelectLists ist nie zu "Enthalten" zu einem string, also das Element.Ausgewählt wird nie gesetzt.(Korrektur:tatsächlich, nach mehr tracing mit dem debugger habe ich festgestellt, dass selectedValues ist abgeleitet von dem defaultValue von einem "ToString()" aufrufen.Also es ist eigentlich eine Liste von Zeichenfolgen, aber anstatt mit den Werten, die wir wollen, es enthält " - System.Web.Mvc.SelectList" - das Ergebnis der Anwendung "ToString()" zu komplexen Objekt wie eine Auswahlliste.Das Ergebnis ist immer noch dasselbe - wir sind nicht gehen zu finden, der Wert, den wir suchen, in dieser Liste.)

Es ersetzt dann die neu errichtete "newSelectList" für das original "selectList", und fährt zum erstellen der HTML-von es.

Als cagdas (ich entschuldige mich für Schlachten Ihre Namen, aber ich weiß nicht, wie man diese Zeichen auf meiner US-Tastatur) oben gesagt, ich denke, ich werde das schaffen müssen, um meine eigene Methode zu verwenden, an die Stelle der DropDownList HtmlHelper.Ich denke, da dieses release 1 und Release2 ist in der Beta 2, können wir nicht wirklich erwarten, dass jeder Fehler behebt es sei denn, wir tun es uns selbst Recht?

BTW, wenn du das befolgt hast mich so weit, sich dieser code in src\SystemWebMvc\Mvc\Html\SelectExtensions.cs, at around line 116-136

Ja, ich hatte auch so viele Probleme bekommen Dropdown das ausgewählte Element zu respektieren ich ihm gegeben habe.

Bitte überprüfen Sie meine Antwort auf diese Frage . Soweit ich mich erinnern kann, dass der einzige Weg war, konnte ich es an die Arbeit. Durch die Übergabe der Liste über Viewdata.

FYI, hörte ich, dass Htmlhelper Methode. Ich bin jetzt einfach die <select> und <option> Tags selbst mit einer Schleife ausgeben und die selected Eigenschaft des option Tages einstellen, indem sie es selbst zu überprüfen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top