2012-04-15 3 views
0
bindet

In meiner Anwendung habe ich eine Dropdown-Liste, um verschiedene Auswahlmöglichkeiten darzustellen. Beachten Sie, dass Paragraph ein Modell ist und der Abschnitt nur ein Feld im Modell ist.MVC 3 Dropdown-Liste, die nicht an Modell

Und hier ist mein Controller.

public ActionResult Edit(int id) 
{ 
    var paragraph = db.Paragraphs.Find(id); 

    ViewBag.Sections = new SelectList(
     db.Sections.Select(s => new { s.ID, s.Name }), 
     "ID", "Name", paragraph.SectionID 
    ); 

    return View(paragraph); 
} 

[HttpPost] 
public ActionResult Edit(Paragraph paragraph, HttpPostedFileBase document) 
{ 
    if (ModelState.IsValid) 
    { 
     // Do some stuff. 
    } 

    ViewBag.Sections = new SelectList(
     db.Sections.Select(s => new { s.ID, s.Name }), 
     "ID", "Name", paragraph.SectionID 
    ); 

    return View(paragraph); 
} 

Wenn ich das Formular absende, ist die Dropdown-Liste nicht an das Modell gebunden. ModelState.IsValid zu verursachen, um falsch zu sein und mein Leben schrecklich zu machen. Irgendwelche Vorschläge?

EDIT: Wenn ich die Form ich folgende Fehlermeldung erhalten einreichen:

There is no ViewData item of type 'IEnumerable<SelectListItem>' that has the key 'Sections'. 

EDIT: Es scheint, dass ich die vorhergehenden Fehler nur, wenn ich versuche, die Datei zu senden.

EDIT: Modell

public class Paragraph 
{ 
    public int ID { get; set; } 

    [Required] 
    public int Major { get; set; } 

    [Required] 
    public int Minor { get; set; } 

    [Required(ErrorMessage = "Name is required")] 
    [StringLength(4000)] 
    public string Name { get; set; } 

    public int SectionID { get; set; } 
    public virtual Section Section { get; set; } 
} 

Form: (. Es ist viel)

<form class="form-horizontal" action="/Paragraph/Edit" method="post" enctype="multipart/form-data"> 
    <fieldset> 
     <div class="control-group"> 
      <label class="control-label" for="section">Section</label> 
      <div class="controls"> 
       @Html.DropDownList("Sections") 
      </div> 
     </div> 
     <div class="control-group"> 
      <label class="control-label" for="major">Major</label> 
      <div class="controls"> 
       <input type="number" class="input-large" name="major" value="@Model.Major" /> 
      </div> 
     </div> 
     <div class="control-group"> 
      <label class="control-label" for="minor">Minor</label> 
      <div class="controls"> 
       <input type="number" class="input-large" name="minor" value="@Model.Minor" /> 
      </div> 
     </div> 
     <div class="control-group"> 
      <label class="control-label" for="name">Name</label> 
      <div class="controls"> 
       <input type="text" class="input-large" name="name" value="@Model.Name" /> 
      </div> 
     </div> 
     <div class="control-group"> 
      <label class="control-label" for="document">Document</label> 
      <div class="controls"> 
       <input type="file" class="input-file" name="document" /> 
      </div> 
     </div> 
     <div class="form-actions"> 
      <input type="submit" class="btn btn-primary" value="Save" /> 
      <a class="btn" href="/Paragraph/Show/@Model.ID">Cancel</a> 
     </div> 
    </fieldset> 
</form> 

Antwort

0

Diese spät, aber besser spät als noch nie. Wenn Sie einen der Helfer von HtmlHelper verwenden, wird der Name input hinter den Kulissen generiert. Das generierte Format für diesen Namen lautet Model.Field. Beispielsweise würde ein Absatz mit einem Feld namens "Name" Paragraph.Name werden.

Die Definition für DropDownList, die einen Parameter akzeptiert, verwendet den Namen der Dropdown-Liste als den Namen der input obwohl. Also würde ein Anruf an DropDownList("Sections") eine input mit einem Namen von "Sektionen" erstellen.

Am Ende entschied ich jedoch, Razor zuzugeben und die eingebauten HTML-Helfer zu verwenden. So sieht mein Dropdown-Listen-Code wie folgt aus: DropDownListFor(vm => vm.Paragraph.SectionID, Models.Sections).

+1

Die Verwendung von ViewModels und stark typisierten Helfern ist im Allgemeinen der richtige Weg. Ich bin froh, dass du es sortiert hast. – GraemeMiller

1

Nur frage mich, warum Sie nicht stark Helfer geben wie Html.TextBoxFor etc verwenden? Sie können mit ihnen passieren optional HTML-Attribute können bei Bedarf

Ich würde machen Ihre Dropdownlist

@Html.DropDownListFor(model =>model.SectionID,(IEnumerable<SelectListItem>) ViewBag.Sections) 

Andere

@Html.HiddenFor(model =>model.ID) 
@Html.TextBoxFor(model =>model.Name) 
@Html.TextBoxFor(model =>model.Major) 
@Html.TextBoxFor(model =>model.Minor) 

Datei <input type="file" class="input-file" name="document" />

sein, dass Sie das Modell geben sollte zu binden. Sie werden sicher sein, die richtigen Namen usw. zurück zu bekommen. Auch ich schließe die ID als Teil des Formulars ein.

+0

ich meine Frage (erster Absatz) aktualisiert, um ein paar Details. Grundsätzlich ist die Dropdown-Liste Teil eines Modells und nicht an das Modell gebunden. –

+0

Können Sie die Form der Ansicht und das Absatzmodell veröffentlichen? – GraemeMiller

1

Ihren HTML-Code ändern:

@Html.DropDownListFor(m => m.SectionID, ViewBag.Sections as SelectList) 

Wenn Sie diese Seite nicht ein Modell, dann den Code unten verwenden:

@Html.DropDownList("Sections", ViewBag.Sections as SelectList) 
+0

Es ist wirklich komisch. Es funktioniert für "GET" und auf "POST", wenn ich keine Datei hochlade. Aber wenn ich eine Datei anliege, flippt es aus und Fehler. –

+0

Was ist der Fehler? –

+0

Haben Sie verschiedene Dateien ausprobiert? Weder eine Datei noch eine Eigenschaft namens Dokument sind im Modell enthalten, daher ist nicht sicher, warum das Vorhandensein oder Nichtvorhandensein einer Datei die Validierung des Modellzustands beeinträchtigt. – GraemeMiller

0

So komisch!Ich benutzte

@Html.DropDownList("permissionsID", String.Empty) 

zu verwenden und es funktionierte gut - ganz plötzlich, im das gleiche Problem erhalten. Die DDL ist nicht seine gewählte Wert Vorlage auf dem Create (geschrieben) Controller-Methode)

So verwendete ich

@Html.DropDownListFor(model => model.permissionID, (IEnumerable<SelectListItem>)ViewBag.permissionsID) 

und es funktionierte gut!

Allerdings habe ich ältere Controller, die auch heute noch mit der alten Methode arbeiten - nur nicht so für meine neuen Controller!

Es ist wirklich Logik trotzt ...

+0

Willkommen auf der Seite - könnten Sie das so umformulieren, dass es eher wie eine Antwort auf die Frage liest, anstatt laut zu denken? Vielen Dank! – BoltClock

0

Freund hatte das gleiche Problem, wenn Dropdownlist zu tun Kaskadierung

Und es gibt keinen Grund Mutterdropdownlist zu binden. Also, was ich getan habe, war die Eltern Dropdown-Liste auf die gleiche Weise wie die bald füllen. Eine Aktion erstellt, sie in json aufgerufen und mit jquery gefüllt.

Meine Aktion Controller:

public ActionResult GetStates() 
    { 
     if (Request.IsAjaxRequest()) 
     { 
      using (MyModel banco = new myModel()) 
      { 

       return Json(new SelectList(banco.SyStates.ToList(), "StateId", "StateName"), JsonRequestBehavior.AllowGet); 

      } 
     } 
     return View(); 

    } 

Aussicht:

 <select id="StateList" name="StateList"></select> 

<script> 

    $(document).ready(function() { 



     var URL = "/ControllerName/GetStates"; 
     $.getJSON(URL, function (data) { 



     var items = '<option>Selecione o estado</option>'; 
     $.each(data, function (i, State) { 
      items += "<option value='" + State.Value + "'>" + State.Text + "</option>"; 
      // state.Value cannot contain ' character. We are OK because state.Value = cnt++; 

     }); 
     $('#StateList').html(items); 
     //$('#CitiesTrID').show(); 

    }) 

}); 

Got Kaskadierung Beispiel auf: http://blogs.msdn.com/b/rickandy/archive/2012/01/09/cascasding-dropdownlist-in-asp-net-mvc.aspx

Verwandte Themen