Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ';对象';不包含';X';_C#_Asp.net Mvc_Razor - Fatal编程技术网

C# ';对象';不包含';X';

C# ';对象';不包含';X';,c#,asp.net-mvc,razor,C#,Asp.net Mvc,Razor,我以前有过一次这个问题,但没有解决。我有一个列表(在MVC3控制器中生成): 在我的页面(Razor)上,我尝试迭代: foreach (var o in ViewBag.Languages) { string img = "Lang/" + o.EnglishName + ".png"; @* work *@ } 但是对o.EnglishName的引用失败,出现错误: “object”不包含“EnglishName”的定义 尽管奇怪的是,如果我在即时窗口中键入(调试时): 很

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

在我的页面(Razor)上,我尝试迭代:

foreach (var o in ViewBag.Languages)
{
    string img = "Lang/" + o.EnglishName + ".png";
    @* work *@
}
但是对
o.EnglishName
的引用失败,出现错误:

“object”不包含“EnglishName”的定义

尽管奇怪的是,如果我在即时窗口中键入(调试时):


很明显,这个领域是存在的。我这里有什么问题?

您在这里使用的是匿名对象:

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();
然后在控制器中使用此视图模型:

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()

在我检查代码并发现以下内容之前,这让我非常紧张:

class AdsViewModel
{
    public int Id { get; set; }
    public  string City { get; set; }
    public string CompanyName { get; set; }
    public string ContactName { get; set; }
    public string UserEmail { get; set; }
    public string ContactPhone { get; set; }
    public string ShortTitle { get; set; }
    public string AdUrl { get; set; }
}
将其更改为:

public class AdsViewModel 

已修复。

如果类的名称与文件的名称不匹配,也可能发生这种情况(我知道这很愚蠢,但可能会对您有所帮助)

请使用ViewData,而不是像ViewBag一样使用ViewBag

ViewData["Lang"] = db.Languages
.Select(x => new { x.Name, x.EnglishName, x.Id })
.ToList();
然后


哇!真棒的回答(+1)。非常感谢-是的,我正在删除对ViewBag的所有引用以支持视图模型…非常好,但有时我们可能需要ViewBag。我们只能将一个模型传递给一个视图。然而,我们可能想发送一些其他的小数据收集,不是吗?在这种情况下,使用ViewBags发送小数据收集会更容易。当然你也可以用partialview发送。我不知道还有其他建议吗。@Darin-我不知道匿名对象,特别是ExpandooObject属性,在另一个程序集中是不可访问的。他们并没有将“对象”视为“属性”。当你说它们是内在的时候,这是有道理的。这帮助我解决了VSTO场景中的问题。新的{}才是真正的交易。谢谢似乎是特定的嵌套类会导致问题。真正的答案如下:
ViewData["Lang"] = db.Languages
.Select(x => new { x.Name, x.EnglishName, x.Id })
.ToList();
foreach (var o in (dynamic) ViewData["Lang"])
{
string img = "Lang/" + o.EnglishName + ".png";
@* work *@
}