如何在MVC中处理ViewData类型转换

时间:2010-04-21 18:54:28

标签: c# asp.net asp.net-mvc

我是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格式检索值。

感谢。

4 个答案:

答案 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可能是使用它的原因。