Używasz anonimowego obiektu tutaj:
ViewBag.Languages = db.Languages
.Select(x => new { x.Name, x.EnglishName, x.Id })
.ToList();
anonimowych obiekty są emitowane jako internal
przez kompilator. Widoki Razor są automatycznie kompilowane do osobnego zestawu przez środowisko wykonawcze ASP.NET. Oznacza to, że nie masz dostępu do żadnych anonimowych obiektów wygenerowanych w kontrolerach.
Zatem w celu ustalenia problemu można zdefiniować model wyświetlania:
public class LanguageViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public string EnglishName { get; set; }
}
a potem w użytku kontrolera ten widok model:
ViewBag.Languages = db.Languages
.Select(x => new LanguageViewModel
{
Name = x.Name,
EnglishName = x.EnglishName,
Id = x.Id
})
.ToList();
a teraz, że masz widok modelu następnym ulepszeniem twojego kodu jest oczywiście pozbyć się tego gówna z ViewBag
, że mam dość widzenia i po prostu używać modeli widoku i silnego pisania:
public ActionResult Foo()
{
var model = db
.Languages
.Select(x => new LanguageViewModel
{
Name = x.Name,
EnglishName = x.EnglishName,
Id = x.Id
})
.ToList();
return View(model);
}
i wtedy oczywiście mieć silnie typami widok:
@model IEnumerable<LanguageViewModel>
@Html.DisplayForModel()
a następnie zdefiniować odpowiedni szablon wyświetlania, które zostaną automatycznie świadczonych przez silnik ASP.NET MVC dla każdego elementu modelu widoku, dzięki czemu don „t nawet trzeba pisać pojedynczy foreach w widokach (~/Views/Shared/DisplayTemplates/LanguageViewModel.cshtml
):
@model LanguageViewModel
... generate the image or whatever you was attempting to do in the first place
wow. wspaniała odpowiedź (+1 za to). dziękuję bardzo - i tak, jestem w trakcie usuwania wszystkich odwołań do ViewBag na rzecz modeli-widoków ... – ekkis
bardzo dobrze, ale czasami możemy potrzebować ViewBags. Możemy przekazać tylko jeden model do jednego widoku. Jednak możemy chcieć wysłać trochę innych małych zbiorów danych, nieprawdaż? w tym przypadku łatwiej jest wysłać tę małą kolekcję danych za pomocą ViewBags. Oczywiście możesz też przesłać go z PartialViews. Nie wiem, czy są jakieś inne zalecenia. – oneNiceFriend