您在此处使用了一个匿名对象:
ViewBag.Languages = db.Languages
.Select(x => new { x.Name, x.EnglishName, x.Id })
.ToList();
匿名对象由编译器作为internal
发出。Razor视图会被ASP.NET运行时自动编译成单独的程序集。这意味着您无法访问在控制器中生成的任何匿名对象。
因此,为了解决问题,您可以定义一个视图模型:
public class LanguageViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public string EnglishName { get; set; }
}
然后在您的控制器中使用此视图模型:
ViewBag.Languages = db.Languages
.Select(x => new LanguageViewModel
{
Name = x.Name,
EnglishName = x.EnglishName,
Id = x.Id
})
.ToList();
现在你有了一个视图模型,接下来改进你的代码的自然步骤是摆脱这个我已经厌烦看到的ViewBag
,并且简单地使用视图模型和强类型:
public ActionResult Foo()
{
var model = db
.Languages
.Select(x => new LanguageViewModel
{
Name = x.Name,
EnglishName = x.EnglishName,
Id = x.Id
})
.ToList();
return View(model);
}
然后当然需要有一个强类型视图:
@model IEnumerable<LanguageViewModel>
@Html.DisplayForModel()
接着定义相应的显示模板,ASP.NET MVC引擎会自动为视图模型中的每个元素呈现该模板,因此您甚至不需要在视图中编写任何foreach语句(~/Views/Shared/DisplayTemplates/LanguageViewModel.cshtml
):
@model LanguageViewModel
... generate the image or whatever you was attempting to do in the first place