-1

Ich habe das folgende Problem.MVC: DropDownListFor Fehler "kann Lambda-Ausdruck nicht in Typ 'String' konvertieren, weil es kein Delegate-Typ ist"

Ich habe eine Tabelle, die Users genannt wird, und ich habe eine andere Tabelle namens Department.

Jetzt möchte ich, dass in der Benutzeroberfläche, wenn ein Benutzer sich selbst als Benutzer mit dem Benutzerformular erstellen wird, dass er auf dem Abteilungsfeld eine Dropdown-Liste alle Abteilung Titel, die aus Abteilung Tabelle verfügbar sind. Grund dafür: Die Abteilungstabelle wird für andere Operationen verwendet und sollte nicht mit den Benutzerdaten verknüpft werden. Daher sollten die Benutzerdaten nur den Abteilungsnamen aus der Tabelle enthalten, und das ist genug.

My-Controller wie folgt aussieht:

public ActionResult UserCreate() 
{ 
    ViewBag.AppDataDepartment = new SelectList(database.department, "department_title", "department_title"); 
    return View(); 
} 

[HttpPost] 
public ActionResult UserCreate(Users user) 
{ 
    if (user.UserID == "" || user.UserID == null) 
    { 
     ModelState.AddModelError(string.Empty, "UserID cannot be blank"); 
    } 
    try 
    { 
     if (ModelState.IsValid) 
     { 
      List<string> results = database.Database.SqlQuery<String>(string.Format("SELECT UserID FROM USERS WHERE UserID = '{0}'", user.UID)).ToList(); 
      bool _userExistsInTable = (results.Count > 0); 
      Users _user = null; 
      if (_userExistsInTable) 
      { 
       _user = database.Users.Where(p => p.UserID == user.UserID).FirstOrDefault(); 
       if (_user != null) 
       { 
        if(_user.active == true) 
        { 
          ModelState.AddModelError(string.Empty, "USER already exists!"); 
        } 
        else 
        { 
         database.Entry(_user).Entity.active = true; 
         database.Entry(_user).Entity.Last_Modified = System.DateTime.Now; 
         database.Entry(_user).State = EntityState.Modified; 
         database.SaveChanges(); 
         return RedirectToAction("Index"); 
        } 
       } 
      } 
      else 
      { 
       _user = new Users(); 
       _user.UserID = user.UserID; 
       _user.lastname = user.lastname; 
       _user.firstname = user.firstname; 
       _user.mail = user.mail; 
       _user.department = user.department; 
       _user.user_image = user.user_image; 
       _user.image_path = user.image_path; 
       if (ModelState.IsValid) 
       { 
        _user.active = true; 
        _user.Last_Modified = System.DateTime.Now; 
        database.Users.Add(_user); 
        database.SaveChanges(); 
        ViewBag.AppDataDepartment = new SelectList(database.department, "department_title", "department_title"); 
        return RedirectToAction("Index"); 
       } 
      } 
     } 
    } 
    catch (Exception ex) 
    { 
     //return base.ShowError(ex); 
    } 
    return View(user); 
} 

Das ist mein HTML-Abschnitt ist:

<div class="row"> 
    @Html.LabelFor(model => model.UserID, "UserID", new { @class = "col-sm-2 control-label" }) 
    <div class="col-md-4"> 
     @Html.TextBoxFor(model => model.UserID, new { @class = "col-md-4 control-label form-control", @id = "inputEmail3" }) 
    </div> 

    @Html.LabelFor(model => model.department, "Department", new { @class = "col-sm-2 control-label" }) 
    <div class="col-md-4"> 
     @Html.DropDownList(model => model.department, (SelectList) ViewBag.AppDataDepartment, htmlAttributes: new { @class = "form-control" }) 
    </div> 
</div> 

Und schließlich meine Abteilung Klasse aus der Tabelle:

[Table("department")] 
public partial class department 
{ 
    [Key] 
    public int departmentid { get; set; } 
    [Required] 
    public string department_title { get; set; } 
    public string subdepartment { get; set; } 
} 

Aber ich kann nicht kompilieren, weil ich den Fehler bekomme:

Error CS1660 Cannot convert lambda expression to type 'string' because it is not a delegate type BTKPI

Warum funktioniert das nicht? Wie kann ich das beheben?

Ich habe mir schon diese SolutionProposal angesehen, aber das hat nicht geholfen, weil das Modell, Linq und Data.Entity bereits referenziert ist.

+3

'@ Html.DropDownListFor()' nicht '@ Html.DropDownList()' –

+0

@StephenMuecke danke, aber dann bekomme ich folgende Fehlermeldung: Fehler CS1928 \t 'Htmlhelper ' enthält keine Definition für ‚DropDownListFor 'und die beste Erweiterung Methode Überladung' SelectExtensions.DropDownListFor (HtmlHelper , Ausdruck >, IEnumerable , Objekt) 'hat einige ungültige Argumente – Azeristar

+0

Sie haben so viel schlechten Code ist ein Wunder, dass alles funktioniert. An welches Modell binden Sie sich? (Alles, was Sie gezeigt haben, ist 'class department', aber das enthält keine Eigenschaft mit dem Namen' department') –

Antwort

2

Es muss DropDownListFor(), nicht DropDownList()

@Html.DropDownListFor(m => m.department, (SelectList)ViewBag.AppDataDepartment, new { @class = "form-control" }) 

Wenn Sie DropDownList() verwenden wäre, dann wäre es

sein
@Html.DropDownList("department", (SelectList)ViewBag.AppDataDepartment, new { @class = "form-control" }) 

Allerdings gibt es zahlreiche andere Probleme mit Ihrem Code, die beachtet werden sollten .

  1. Ihr Controller sollte Create() so UserController und die Methode sein, dass die URL ../User/Create sein wird, nicht User/UserCreate
  2. Ihre Bearbeitung von Daten, so sollten Sie einen Blick Modell werden (nicht Datenmodelle verwenden bei der Bearbeitung Daten) - siehe What is ViewModel in MVC?, und das Ansichtsmodell sollte eine Eigenschaft enthalten IEnumerable<SelectListItem> DepartmentList - ein typisches Beispiel ist in this question/answer gezeigt.
  3. Ihre Users Tabelle sollte den ID der Department, nicht seinen Namen werden zu speichern, und es sollte eine FK Beziehung zur Departments Tabelle sein.
  4. Ihre Ansicht Modelleigenschaft für UserID sollte ein [Required] Attribut hat und die Aussicht sollte @Html.ValidationMesageFor(m => m.UserID) so enthält, dass Sie bothe Client- und Server-seitige Validierung (dito für die DepartmentID Eigenschaft) erhalten.Sie sollten auch ein RemoteAttribute auf die UserID Eigenschaft angewendet betrachten so , dass Sie Client-seitige Validierung erhalten - How to: Implement Remote Validation in ASP.NET MVC

beziehen Und schließlich, fast nichts ist man POST-Methode viel Sinn macht. Sie rufen die Datenbank zweimal auf, um zu prüfen, ob der Benutzer bereits existiert. Sie überprüfen ModelState.IsValid mehrmals. Ihre Eigenschaften user_image und image_path weisen darauf hin, dass Sie ein Bild hochladen müssen, aber nirgendwo speichern Sie es. Sie weisen ViewBag.AppDataDepartment zu und leiten Sie dann sofort an die Index() Methode um. Der Code soll in etwa so aussehen (die Datei-Upload-Ausgabe ignoriert)

[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult Create(UserVM model) 
{ 
    // Return early 
    if (!ModelState.IsValid) 
    { 
     // You will enter this automatically of UserID is null 
     model.DepartmentList = ... // assign the SelectList 
     return View(model); 
    } 
    // One database call to check if the user exists 
    User user = database.Users.Where(p => p.UserID == model.UserID).FirstOrDefault(); 
    if (user != null && !user.active) 
    { 
     user.active = true; 
     // Save and redirect 
    } 
    else if (user != null) 
    { 
     ModelState.AddModelError(string.Empty, "USER already exists!"); 
     model.DepartmentList = ... // assign the SelectList 
     return View(model); 
    } 
    user = new User 
    { 
     UserID = model.UserID, 
     lastname = model.lastname, 
     .... // set other properties of User 
     Last_Modified = System.DateTime.Now 
    } 
    // Save and redirect 
} 

Obwohl seine unklar, warum ein bestehender Benutzer, der archiviert wurde würde zu einem Create() Verfahren navigieren muß (und ein Formular vorgelegt werden, um ein Ganze zu füllen viele Details, die sie bereits vorher eingegeben haben). Sie sollten eine separate Methode zum Aktivieren zuvor archivierter Benutzer haben.

+0

Eigentlich Dies ist der Administrator User Control. Ich habe ein RBAC-Modell implementiert, das Rollen, Berechtigungen und Benutzer hat. Sie sind alle zusammen in einem Controller-Admin. Deshalb habe ich den Aktionsnamen wie CreateUser, da ich auch CreateRole & CreatePermission habe. Die Links, die du postest, sind sehr hilfreich. – Azeristar

+0

Dann sollten Sie [Bereiche] (http://www.codeguru.com/csharp/.net/net_asp/mvc/article.php/c20227/Using-Areas-in-ASPNET-MVC-Application.htm) –

+0

verwenden Danke, das klingt sehr logisch. Ich werde versuchen, es heute zu implementieren :) Danke für die Hilfe und die Links. – Azeristar

Verwandte Themen