2009-05-30 4 views
2

Ich habe ein Registrierungsformular, das einen Benutzernamen (Textbox), E-Mail (Textbox) und Division (SelectList) anzeigt. Der Name und die E-Mail-Adresse sind bereits ausgefüllt (ich verwende die Windows-Authentifizierung, Intranet-App), und ich möchte den SelectedValue von DropDown als Int32 an meinen Controller senden. Ich möchte nicht die gesamte SelectList zurücksenden. Diese Liste ist jetzt klein, wird aber zu beträchtlicher Größe wachsen.Pass SelectList "SelectedValue" zu Controller Aktionsmethode

I eine Klasse namens RegistrationViewModel, enthält es öffentliche Eigenschaften für diese Felder. Wenn ich jedoch SelectList für die DivisionList verwende, erhalte ich diesen Fehler: No parameterless constructor defined for this object..

Wenn ich den Typ ändern, funktioniert es kein Problem, aber Division ist null oder 0. Gibt es eine Möglichkeit, den SelectedValue von einem DropDown an eine Controller Action-Methode als Int32 übergeben?

Edit 1:

Ich bin nicht wirklich sicher, was ich tue, ich habe etwa 48 Stunden für MVC wurde verwenden, beobachtete das PDF, TechEd und TechDays Videos.

Ich entschuldige mich, hier ist mein Controller-Code:

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Register(RegistrationViewModel rvm) 
{ 
    IApplicationContext context = ContextRegistry.GetContext(); 
    IValidationErrors errors = new ValidationErrors(); 

    IValidator validator = (IValidator)context.GetObject("RegistrationValidator"); 
    bool valid = validator.Validate(rvm, errors); 

    if (valid) 
     repo.SaveRegistration(); 
    else 
     ViewData["DivisionList"] = repo.GetDivisions(); 

    return View(rvm); 
} 

RegistrationViewModel Klasse

public class RegistrationViewModel 
{ 
    public string Name { get; set; } 
    public string Email { get; set; } 
    //public SelectList DivisionList { get; private set; } 
    public int Division { get; set; }  
} 

Hier ist der Ansicht

<%@ Page Language="C#" 
MasterPageFile="~/Views/Shared/Site.Master" 
Inherits="System.Web.Mvc.ViewPage<RegistrationViewModel>" %> 

<%@ Import Namespace="Project1.Entities"%> 
<%@ Import Namespace="Project1.Models"%> 

<asp:Content ID="registerTitle" ContentPlaceHolderID="TitleContent" runat="server"> 
    Register 
</asp:Content> 

<asp:Content ID="registerContent" ContentPlaceHolderID="MainContent" runat="server"> 
... 
    <% using (Html.BeginForm()) 
     { %> 
     <div> 
      <fieldset> 
       <legend>Account Information</legend> 
       <p> 
        <label for="name">Name:</label> 
        <%= Html.TextBox("Name", User.Identity.Name.GetDisplayName()) %> 
        <%= Html.ValidationMessage("username") %> 
       </p> 
       <p> 
        <label for="email">Email:</label> 
        <%= Html.TextBox("email", User.Identity.Name.GetEmailFromLogin()) %> 
        <%= Html.ValidationMessage("email") %> 
       </p>    
       <p> 
        <label for="division">Division:</label> 
        <%= Html.DropDownList("DivisionList", ViewData["DivisionList"] as SelectList)%> 
        <%= Html.ValidationMessage("confirmPassword") %> 
       </p> 
       <p>     
        <input type="submit" value="Register" /> 
       </p> 
      </fieldset> 
     </div> 
    <% } %> 
</asp:Content> 

Edit 2:

Eilon: Hier i was ich es auch geändert:

Controller:

public ActionResult Register() 
{ 
    ViewData["DivisionList"] = repo.GetDivisions(); 
    return View(); 
} 

Ausblick:

<%= Html.DropDownList("DivisionValue", ViewData["DivisionList"] as SelectList)%> 

Ich erhalte diese Ausnahme: Es gibt keinen Viewdata Punkt mit der Taste 'DivisionValue' vom Typ ‚IEnumerable ".

Als ich den Blick auf diese aktualisiert:

<%= Html.DropDownList("DivisionList", ViewData["DivisionList"] as SelectList)%> 

Es ist einfach großartig funktioniert! Es scheint nur zu funktionieren, wenn alle "Division" -Elemente identisch benannt sind. Wenn ich den Namen ändere, stürzt die View ab oder die ViewModel "Division" Eigenschaft wird als 0 gesendet.

Warum ist das?

public string DivisionValue { get; set; } 

oder die Art ändern, um int, Datum- und oder was auch immer die geeignete Art ist:

+0

Bitte zeigen Sie uns Ihren Controller Action Code. Wie übermittelst du den Wert der E-Mail-Textbox? – ichiban

Antwort

5

Die RegistrationViewModel Art eine einfache typisierte Eigenschaft wie enthalten sollte.

In HTML und HTTP wird nur der Name des Felds und der ausgewählte Wert für eine Dropdown-Liste zurückgesandt.

alles zu bekommen, um bis Sie müssen auch die Ansicht ändern, eine andere Eingabe Namen für die Dropdown-Liste zu machen:

<%= Html.DropDownList("DivisionValue", ViewData["DivisionList"] as SelectList)%> 

Beachten Sie, dass ich „DivisionValue“ ist der Wert bin mit der Liste und DivisionList als Liste aller verfügbaren Elemente.

0

Ich würde nur expliziter mit der SelectList Art sein. Ich würde vorschlagen, die SelectList in der Controller-Aktion zu erstellen und vergessen, es in der Ansicht zu werfen. Mein Code funktioniert wie folgt (CRUD Seite bearbeiten):

..in der Aktion:

  ViewData["WorkType.ID"] = new SelectList(this._vacancySvc.GetVacancyWorkTypes(), 
      "ID", "Name", ViewData["WorkType.ID"] ?? vacancy.WorkType.ID); 

..und in der Ansicht:

<p><% =Html.Encode("Work Type:") %><br /> 
      <% =Html.DropDownList("Worktype.ID")%><span class="smallgrey">(required)</span><br /> 

.. Sie können sehen, dass entweder die Die erste Auswahl (aus DB) wird beibehalten oder die ViewData von Postbacks (wie wenn das Formular die Validierung nicht bestanden hat) durch die Verwendung des [Koaleszenzoperators null] [1] (??).

Außerdem, wenn ich diesen Code refaktoriert hätte, würde ich wahrscheinlich ein ViewModel-Objekt verwenden möchten, wie Sie sind. Das einzige Ding ist: (1) Sie würden nie die ViewModel SelectList Eigenschaft in der Ansicht referenzieren müssen, die MVC diese für uns durch die Html.DropDownList() Überlastung automatisch bindet .. und (2) würde ich noch die ViewData in beziehen müssen die aktion trotzdem, um den ausgewählten wert von einem fehlgeschlagenen validierungs-post zurück zu bekommen, worauf kommt es wirklich an ??