C# ';对象';不包含';X';
我以前有过一次这个问题,但没有解决。我有一个列表(在MVC3控制器中生成): 在我的页面(Razor)上,我尝试迭代: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”的定义 尽管奇怪的是,如果我在即时窗口中键入(调试时): 很
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 *@
}