Laden...

ASP.Net MVC 5 Bootstrap DropDownListFor() Problem

Erstellt von Gongo82 vor 9 Jahren Letzter Beitrag vor 9 Jahren 5.108 Views
G
Gongo82 Themenstarter:in
41 Beiträge seit 2014
vor 9 Jahren
ASP.Net MVC 5 Bootstrap DropDownListFor() Problem

Hallo Leute,

Ich programmiere derzeit mit Asp.net MVC 5 (VS 2013) und Bootstrap eine Anwendung
ich habe folgendes Problem...
Daten werden tabelarisch dargestellt. Wenn man in eine Zeile "ändern auswählt" sollen die Daten aus diesem Datensatz in einer Edit Page dargestellt und geändert werden können. Das Problem ist, das die Datensätze nicht korrekt in den jeweiligen DropDownListBoxen angezeigt wird...Es wird mir immer der erste Eintrag aus der DropdownListe angezeigt. Ich hoffe ihr versteht was ich meine...

In meiner Index Action werden Daten tabelarisch dargestellt. Man hat für jede Zeile die folgenden Möglichkeiten (Datensätz ändern, löschen, einsehen)
Anzeigen

Wenn man Ändern auswählt wir die folgende Action ausgeführt.



// GET: /Admin/SeminarErstellen/Edit/5
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            tbl_Seminar_erstellen tbl_seminar_erstellen = db.tbl_Seminar_erstellen.Find(id);
            if (tbl_seminar_erstellen == null)
            {
                return HttpNotFound();
            }
            ViewBag.tbl_dozent_id = new SelectList(db.tbl_Dozent, "id", "Name", tbl_seminar_erstellen.tbl_dozent_id);
            ViewBag.tbl_fileUpload_id = new SelectList(db.tbl_FileUpload, "id", "FilePath", tbl_seminar_erstellen.tbl_fileUpload_id);
            ViewBag.tbl_seminar_stati_id = new SelectList(db.tbl_Seminar_Stati, "id", "Status_Typ", tbl_seminar_erstellen.tbl_seminar_stati_id);
            ViewBag.tbl_seminarTyp_id = new SelectList(db.tbl_Seminar_Typ, "id", "Seminarbezeichnung", tbl_seminar_erstellen.tbl_seminarTyp_id);
            return View(tbl_seminar_erstellen);
        }



@model NOK.Models.tbl_Seminar_erstellen

@{
    ViewBag.Title = "Edit";
    Layout = "~/Views/Shared/_Layout.cshtml";
}



@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    
    <div class="form-horizontal">
        <br />
        <br />
        <br />
        <h4>Seminar ändern</h4>
        <hr />
        @Html.ValidationSummary(true)
        @Html.HiddenFor(model => model.id)

        <div class="form-group">
            @Html.LabelFor(model => model.tbl_seminarTyp_id, "tbl_seminarTyp_id", new { @class = "control-label col-md-2" })
            <div class="col-md-3">
                @Html.DropDownList("tbl_Gemeinde_id", String.Empty)
                @Html.DropDownListFor(Model => Model.tbl_seminarTyp_id, (SelectList)ViewBag.tbl_seminarTyp_id, new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.tbl_seminarTyp_id)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.tbl_dozent_id, "tbl_dozent_id", new { @class = "control-label col-md-2" })
            <div class="col-md-3">
                @Html.DropDownListFor(Model => Model.tbl_dozent_id, (SelectList)ViewBag.tbl_dozent_id, new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.tbl_dozent_id)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.tbl_seminar_stati_id, "tbl_seminar_stati_id", new { @class = "control-label col-md-2" })
            <div class="col-md-3">
                @Html.DropDownListFor(Model => Model.tbl_seminar_stati_id, (SelectList)ViewBag.tbl_seminar_stati_id, new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.tbl_seminar_stati_id)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Seminarzeitraum_von, new { @class = "control-label col-md-2" })
            <div class="col-md-3">
                @Html.TextBoxFor(model => model.Seminarzeitraum_von, new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.Seminarzeitraum_von)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Seminarzeitraum_bis, new { @class = "control-label col-md-2" })
            <div class="col-md-3">
                @Html.TextBoxFor(model => model.Seminarzeitraum_bis, new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.Seminarzeitraum_bis)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Anmeldezeitraum_von, new { @class = "control-label col-md-2" })
            <div class="col-md-3">
                @Html.TextBoxFor(model => model.Anmeldezeitraum_von, new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.Anmeldezeitraum_von)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Anmeldezeitraum_bis, new { @class = "control-label col-md-2" })
            <div class="col-md-3">
                @Html.TextBoxFor(model => model.Anmeldezeitraum_bis, new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.Anmeldezeitraum_bis)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Min_Plaetze, new { @class = "control-label col-md-2" })
            <div class="col-md-3">
                @Html.TextBoxFor(model => model.Min_Plaetze, new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.Min_Plaetze)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Max_Plaetze, new { @class = "control-label col-md-2" })
            <div class="col-md-3">
                @Html.TextBoxFor(model => model.Max_Plaetze, new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.Max_Plaetze)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Noch_Verfuegbare_Plaetze, new { @class = "control-label col-md-2" })
            <div class="col-md-3">
                @Html.TextBoxFor(model => model.Noch_Verfuegbare_Plaetze, new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.Noch_Verfuegbare_Plaetze)
            </div>
        </div>

        
            brauch der Admin nicht sehen nur für Dozent zum hochladen der PDF...
            <div class="form-group">
            @Html.LabelFor(model => model.tbl_fileUpload_id, "tbl_fileUpload_id", new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownList("tbl_fileUpload_id", String.Empty)
                @Html.ValidationMessageFor(model => model.tbl_fileUpload_id)
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Speichern" class="btn btn-success" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>


Wäre euch sehr dankbar wenn ihr mir helfen könntet...

16.833 Beiträge seit 2008
vor 9 Jahren
  1. Verwende ViewModels und vermeide - wenn es geht - den ViewBag => ASP.NET MVC - View- und SubmitModels
    Vor allem solltest Du nur DATEN (keine Entitäten!) und keine CONTROLS an eine View übergeben.
  2. Vermeide die HTML Helper sondern schreib das HTML-Zeugs selbst. Wirkt zwar so, dass das ein Mehraufwand wär; aber Du hast alles selbst unter Kontrolle und ist in der Laufzeit auch performanter.
  3. Deine URL macht kein Sinn. Wenn keine ID mitgegeben wird, also int null wäre, dann würde die Action gar nicht aufgerufen werden (Vorausgesetzt Du hast die Route korrekt definiert).
  4. Verwende Url.Route und vermeide ActionLinks. Die sind ca. 30 mal langsamer in der Laufzeit

Du bist insgesamt besser bedient wenn Du die Daten via AngularJS anzeigst (wenn Du eh schon Bootstrap verwendest) und das Formular dann mit einem fertigen Model absendest. Insgesamt die geringste Tipparbeit mit der höchsten Gewährleistung, dass die Daten wie gewünscht bei der Action ankommen.
Also eine Mischung aus Single-Page-Application und ASP.NET MVC; einfach die saubere Datenbindung. Kann ich nur empfehlen. Spart viel Zeit.

Und eine saubere Trennung der Schichten zur Businesslogik (Services) und Daten (Repository Pattern) wäre auch empfehlenswert.

G
Gongo82 Themenstarter:in
41 Beiträge seit 2014
vor 9 Jahren

Hi,

Danke für die schnelle Antwort...du hast sicherlich recht mit den angesprochenen Punkten von dir. Sicherlich ist es zu empfehlen mehrere layers für ein Projekt aufzusetzen um die Verantwortlichkeiten besser trennen zu können usw. jedoch lautete meine Frage, warum die dropdownlist in der edit view nicht die korrekten Daten anzeigt.Die ViewBags haben alle die richtigen id's und diese sollten eigentlich in der edit view der dropdownlist übergeben und angezeigt werden..aaaaber genau das funktioniert nicht...es wird der erste Eintrag der dropdownlist angezeigt und genau das wollte ich hier besprechen....

16.833 Beiträge seit 2008
vor 9 Jahren

Reicht Dir die Antwort: weil die HtmlHelper sch* sind? 😉

Die SelectList erzeugt SelectListItems.
Die hat die Property Value vom Typ String. Du vergleichst ein Int - KÖNNTE nun ein Problem sein.

Schau Dir zum Beispiel Three ways to populate selected value in DropDownList on Edit or Update views - MVC. 3 Möglichkeiten; keine davon wirklich sauber.
Das ist auch das Problem der Helper. Eine saubere Lösung gibt es gar nichts.

Ich kann Dir spezifisch nicht helfen, weil ich Helper an jeder Stelle meide, wo es geht und nicht aufgrund der vielen Erfahrung absolut abraten kann, dieses Zeug zu verwenden.* Nicht debug-fähig

  • Langsam
  • Benötigt Magic-Strings und damit 0 Punkte für die Wartbarkeit.
  • Unterstützen keine Collections *...

Sogar MS selbst vermeidet in seinen aktuelleren Beispielen mittlerweile die Helper für HTML Formulare 😉

G
Gongo82 Themenstarter:in
41 Beiträge seit 2014
vor 9 Jahren

Hey,

das war mal ne klare Ansage 😃 ich werde deinen Rat die Helpers auszulassen ausprobieren...

Hast du mir ein Beispiel wie das dann in meinem Fall aussehen müsste/könnte? Ich meine die edit page (eine combobox würde auslangen als Beispiel)...nur wenn es kein großer Aufwand für dich ist und du nichts besser zu tun hast 😉

Wäre super...

16.833 Beiträge seit 2008
vor 9 Jahren

Wie gesagt.. ASP.NET MVC - View- und SubmitModels


public class MyViewModel
{
  public List<SelectListItem> DropDownListItems {get;set;}
}

public ActionResult Action(...)
{
...

  var vm = new MyViewModel();
  ...
  
  foreach(var item in myDbCollection)
  {
    var sli = new SelectListItem { Text = item.Name, Value = item.Id.ToString(), Selected = ( überprüfung hier ) };
	vm.DropDownListItems.Add(sli);
  
}

View

<select id="Name-für-submitmodel-hier-setzen" name="Name-für-submitmodel-hier-setzen">
   @foreach(var item in Model.DropDownListItems)
   {
       if(item.Selected)
	   {
	      <option value="@(item.Value)" selected="selected">@(item.Text)</option>
	   }
	   else
	   {
	         <option value="@(item.Value)">@(item.Text)</option>
	   }
   }
</select>

Wenn Du Dir auf dieser Basis (über PartialViews) eigene Helper baust bist Du quasi auf dem optimalen Weg.

G
Gongo82 Themenstarter:in
41 Beiträge seit 2014
vor 9 Jahren

Super... Danke

1.346 Beiträge seit 2008
vor 9 Jahren

@Abt Sollte nicht ein


@foreach(...)
{
    <option value="@(item.Value)" selected="@(item.Selected)">@(item.Text)</option>
}

ausreichend sein? Oder gibt es da dann auch Probleme?

LG

16.833 Beiträge seit 2008
vor 9 Jahren

Einige Bibliotheken erfordern hier selected="selected"; zB hatte jQuery Mobile damit enorme Probleme am Anfang, wenn es nicht selected als Value war.
Streng genommen wäre selected="True" ungültiges HTML.

Edit: Razor scheint in der neuen Variante direkt ein selected="selected" zu machen. Danke für den Hinweis pdelvo.