Ich habe mir eine ganze Nacht lang den Kopf über ein Problem gekratzt, das ich schnell mit Ajax/Jquery und gespeicherten Prozeduren lösen kann. Ich möchte
1) Füllen Sie eine Dropdown-Liste mit Werten aus einer Datenbanktabelle, die Entity Framework und das Ansichtsmodell verwenden. Ich möchte VIEWBAG OR VIEWDATA NICHT VERWENDEN. Jede Hilfe geschätzt.
2) Wie kann ich eine Ansicht erstellen, indem das Ansichtsmodell mit allen Standardfeldern verwendet wird? Das Gerüst arbeitet an einem Modell, aber nicht an einem Sichtmodell?
MEINE MODELLE
public class Employee
{
public int EmployeeID { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public string City { get; set; }
public string Level { get; set; }
public int DepartmentId { get; set; }
}
public class Grade
{
public int ID { get; set; }
public string Level { get; set; }
}
Modell anzeigen
public class GradeSelectListViewModel
{
public Employee Employee { get; set; }
public IEnumerable<SelectListItem> Grades { get; set; }
public GradeSelectListViewModel(Employee employee, IEnumerable grades)
{
Employee = employee;
Grades = new SelectList(grades, "Grade", "Name", employee.Level);
}
}
MEINE KONTEXTKLASSE
public class EmployeeContext : DbContext
{
public DbSet<Employee> Employees { get; set; }
public DbSet<Department> Departments { get; set; }
public DbSet<Grade> Grades { get; set; }
}
MEIN CONTROLLER
public ActionResult Edit (int? id)
{
using (var db = new EmployeeContext())
{
var model = new GradeSelectListViewModel(db.Employees.Find(id), db.Grades);
//model.Employee = db.Employees.Single(x => x.EmployeeID == id);
model.Grades = db.Grades.ToList().Select(x => new SelectListItem
{
Value = x.ID.ToString(),
Text = x.Level
});
return View(model);
}
}
MEINE RAZOR-SEITE CSHTML
@model MVCDemo.ViewModels.GradeSelectListViewModel
....
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
....
@Html.DropDownListFor(x => Model.Employee.Level,
new SelectList(Model.Grades, "ID", "Level"),
"Select Level")
....
<input type="submit" value="Create" class="btn btn-default" />
}
Das Hauptproblem ist, dass in der Ansicht new SelectList(Model.Grades, "ID", "Level")
vorhanden ist, Grades
jedoch IEnumerable<SelectListItem>
ist und SelectListItem
keine Eigenschaften mit den Namen ID
und Level
enthält.
Es gibt jedoch einige andere Probleme mit Ihrem Code. Zunächst sollte ein Ansichtsmodell kein Datenmodell enthalten, und stattdessen sollte es Ihr Ansichtsmodell sein
public class GradeSelectListViewModel
{
public int? ID { get; set; } // make this ID so you do not need an input for it
public string Name { get; set; }
.... // other properties of Employee that your editing
[Required(ErrorMessage = "..")]
public int? Level { get; set; } // make value types nullable to protect against under-posting attacks
public IEnumerable<SelectListItem> Grades { get; set; }
}
und fügen Sie nach Bedarf Anzeige- und Validierungsattribute hinzu. Beachten Sie, dass ich den Konstruktor gelöscht habe (Sie scheinen ihn nicht zu verwenden, aber wenn dies der Fall ist, müssen Sie auch einen parameterlosen Konstruktor hinzufügen. Andernfalls wird beim Senden an die Methode POST eine Ausnahme ausgelöst.) Ich gehe auch davon aus, dass Level
typeof int
sein sollte, da Sie an die int ID
-Eigenschaft von Grade
gebunden werden.
Der Code in Ihrer GET-Methode sollte sein
Employee employee = db.Employees.Find(id);
var model = new GradeSelectListViewModel()
{
ID = employee.EmployeeID,
Name = employee.Name,
Level = employee.Level, // convert to int?
....
Grades = db.Grades.Select(x => new SelectListItem
{
Value = x.ID.ToString(),
Text = x.Level
})
};
return View(model);
und in der Ansicht
@Html.DropDownListFor(x => Model.Level, Model.Grades, "Select Level")
Beachten Sie auch, dass Sie in der Methode POST die Variable SelectList
neu zuweisen müssen, wenn Sie die Ansicht zurückgeben, da ModelState
ungültig ist.
Sie können den folgenden Ansatz verwenden, der drei DropDownListFor in derselben View auffüllt:
ViewModel:
public class GroupViewModel
{
public IEnumerable<SelectListItem> Schedules { get; set; }
public int ScheduleId { get; set; }
public IEnumerable<SelectListItem> Labs { get; set; }
public int LabId { get; set; }
public IEnumerable<SelectListItem> Terms { get; set; }
public int TermId { get; set; }
}
Controller:
public ActionResult Create()
{
//Populate DropDownList binding values
var model = new GroupViewModel
{
//Preselect the Lab with id 2
//LabId = 2,
Labs = repository.Labs.Select(c => new SelectListItem
{
Value = c.Id.ToString(),
Text = c.Name
}),
Terms = repository.Terms.Select(c => new SelectListItem
{
Value = c.Id.ToString(),
Text = c.Name
}),
Schedules = repository.Schedules.Select(c => new SelectListItem
{
Value = c.Id.ToString(),
Text = c.Name
})
};
return View("Create", model);
}
Aussicht:
@Html.DropDownListFor(m => m.LabId, new SelectList(Model.Labs, "Value", "Text"),
"Select", new { @class = "selectpicker" })
@Html.DropDownListFor(m => m.ScheduleId, new SelectList(Model.Schedules, "Value", "Text"),
"Select", new { @class = "selectpicker" })
@Html.DropDownListFor(m => m.TermId, new SelectList(Model.Terms, "Value", "Text"),
"Select", new { @class = "selectpicker" })
Hoffe das hilft...