“对象"不包含“X"的定义 [英] 'object' does not contain a definition for 'X'

查看:26
本文介绍了“对象"不包含“X"的定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我以前遇到过这个问题,但没有解决.我有一个列表(在 MVC3 控制器中生成):

ViewBag.Languages = db.Languages.Select(x => new { x.Name, x.EnglishName, x.Id }).ToList();

在我的页面 (Razor) 上,我尝试遍历它:

foreach(ViewBag.Languages 中的 var o){string img = "Lang/" + o.EnglishName + ".png";@* 工作 *@}

但是对 o.EnglishName 的引用失败并出现错误:

<块引用>

'object' 不包含 'EnglishName' 的定义

虽然奇怪的是,如果我在即时窗口中输入(调试时):

<块引用>

o{ 姓名 = བོད་སྐད་,英文姓名 = 藏文,Id = 31 }英文名称:藏族"编号:31名称:བོད་སྐད་"

很明显,这个领域就在那里.我这里有什么问题?

解决方案

您在此处使用匿名对象:

ViewBag.Languages = db.Languages.Select(x => new { x.Name, x.EnglishName, x.Id }).ToList();

匿名对象由编译器作为 internal 发出.Razor 视图由 ASP.NET 运行时自动编译为单独的程序集.这意味着您无法访问控制器中生成的任何匿名对象.

因此,为了解决您的问题,您可以定义一个视图模型:

公共类 LanguageViewModel{公共 int Id { 获取;放;}公共字符串名称 { 获取;放;}公共字符串EnglishName { get;放;}}

然后在你的控制器中使用这个视图模型:

ViewBag.Languages = db.Languages.Select(x => new LanguageViewModel{名称 = x.Name,英文名 = x.EnglishName,Id = x.Id}).ToList();

现在你有了一个视图模型,你的代码的下一个改进当然是摆脱我讨厌看到的 ViewBag 的废话,只需使用视图模型和强类型:

public ActionResult Foo(){无功模型= db.语言.Select(x => new LanguageViewModel{名称 = x.Name,英文名 = x.EnglishName,Id = x.Id}).ToList();返回视图(模型);}

当然还有一个强类型视图:

@model IEnumerable@Html.DisplayForModel()

然后定义相应的显示模板,由ASP.NET MVC引擎为视图模型的每个元素自动呈现,这样你甚至不需要在你的视图中编写一个foreach(~/Views/Shared/DisplayTemplates/LanguageViewModel.cshtml):

@model LanguageViewModel...生成图像或您首先尝试做的任何事情

I had this problem once before and didn't resolve it. I have a list (generated in an MVC3 controller):

ViewBag.Languages = db.Languages
    .Select(x => new { x.Name, x.EnglishName, x.Id })
    .ToList();

and on my page (Razor) I try to iterate through it:

foreach (var o in ViewBag.Languages)
{
    string img = "Lang/" + o.EnglishName + ".png";
    @* work *@
}

but the reference to o.EnglishName fails with the error:

'object' does not contain a definition for 'EnglishName'

though the curious thing is that if I type into the Immediate Window (whilst debugging):

o
{ Name = བོད་སྐད་, EnglishName = Tibetan, Id = 31 }
    EnglishName: "Tibetan"
    Id: 31
    Name: "བོད་སྐད་"

so obviously the field is there. What is my problem here?

解决方案

You are using an anonymous object here:

ViewBag.Languages = db.Languages
    .Select(x => new { x.Name, x.EnglishName, x.Id })
    .ToList();

Anonymous objects are emitted as internal by the compiler. The Razor views are automatically compiled into a separate assembly by the ASP.NET runtime. This means that you cannot access any anonymous objects generated in your controllers.

So in order to fix your issue you could define a view model:

public class LanguageViewModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string EnglishName { get; set; }
}

and then in your controller use this view model:

ViewBag.Languages = db.Languages
    .Select(x => new LanguageViewModel
    { 
        Name = x.Name, 
        EnglishName = x.EnglishName, 
        Id = x.Id 
     })
    .ToList();

And now that you have a view model the next improvement to your code is of course to get rid of this crap of ViewBag that I am sick of seeing and simply use view models and strong typing:

public ActionResult Foo()
{
    var model = db
        .Languages
        .Select(x => new LanguageViewModel
        { 
            Name = x.Name, 
            EnglishName = x.EnglishName, 
            Id = x.Id 
        })
        .ToList();
    return View(model);
}

and then of course have a strongly typed view:

@model IEnumerable<LanguageViewModel>
@Html.DisplayForModel()

and then define the corresponding display template which will automatically be rendered by the ASP.NET MVC engine for each element of the view model so that you don't even need to write a single foreach in your views (~/Views/Shared/DisplayTemplates/LanguageViewModel.cshtml):

@model LanguageViewModel
... generate the image or whatever you was attempting to do in the first place

这篇关于“对象"不包含“X"的定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆