我是MVC新手,面临一个问题。 我有一个xml文件,我正在使用Linq检索其值到xml并将其分配给ViewData。 Controller.cs
var res=from x in doc.Descendants("person")
select new
{
Fname=x.Element("fname").Value,
Lname=x.Element("lname").Value
};
ViewData["Persons"]=res;
在View中我正在尝试
<% foreach (var item in ViewData["Persons"])
{ %>
<li> <%= item.Fname %> </li>
<% } %>
但是foreach(ViewData [“Persons”]中的var项目给出了类型转换错误..应该是csting的确切类型,以便我可以以item.Fname格式检索值。
感谢。
答案 0 :(得分:8)
尽管可能,使用ViewData
并不是将信息从控制器传递到视图的最佳方式。使用特定的视图模型可以使代码更简单,更清晰,并解决了投射问题。
首先尝试定义模型:
public class ViewModelElement
{
public string Fname { get; set; }
public string LName { get; set; }
}
public class ViewModel
{
public List<ViewModelElement> Elements { get; set; };
}
然后使用您的模型:
public ActionResult ActionName()
{
//get doc somehow
var model = new ViewModel();
//When querying by linq to xml, you can create ViewModelElement instead of anonymous class
model.Elements = (from x in doc.Descendants("person")
select new ViewModelElement
{
Fname=x.Element("fname").Value,
Lname=x.Element("lname").Value
}).ToList();
return View(model);
}
然后在视图中使用您的模型:
<% foreach (var item in model.Elements) { %>
<li> <%= item.Fname %> </li>
<% } %>
视图必须从System.Web.Mvc.ViewPage<ViewModel>
继承。
答案 1 :(得分:0)
非强类型视图的ViewData集合中的默认类型是object。
您的视图正在抛出异常,因为它无法自动从对象强制转换回IEnumerable LINQ查询返回的内容。
将你的循环更改为此,它应该可以正常工作:
<% foreach (var item in (IEnumerable)ViewData["Persons"])
{ %>
<li> <%= item.Fname %> </li>
<% } %>
到目前为止,最好的建议是强烈输入您的观点,以便您可以执行LukLed建议的内容
答案 2 :(得分:0)
现有代码的问题在于您使用Linq查询将数据投影到匿名类型,因此没有要转换的命名类型。
假设您有一个要转换的命名类型(Person)(并且您仍然想使用ViewData),那么您的解决方案将是:
<% foreach (var item in (IEnumerable<Person>)ViewData["Persons"])
但是从强类型的ViewModel对象继承您的页面是一个更好的解决方案。
答案 3 :(得分:0)
就我个人而言,我真的只能想到一个(但我敢肯定还有更多实例)使用视图数据的原因是,这样我就可以在客户端上获取一些数据而无需回调服务器。发出HTTP请求时,通常会针对数据库进行查询并呈现结果。
基于渲染,您很少需要隐藏/存储一些您可能需要或不需要的其他数据,以至于您不希望回调数据库以获取更多数据。此外,数据库上的情况可能已发生更改,使存储的数据无用。会话状态或唯一的用户数据可能会以其他方法存储,但是tbat可能是使用它的原因。