ASP.NET MVC3控制器传递匿名对象到视图解决方法

在ASP.NET MVC3 + Entity Framework项目中,从控制器传递匿名对象到视图非常常见,原本以为用dynamic能轻松搞定,最后发现我错了:

Controller:
public ActionResult Index()
{
    testContext context = new testContext();
    dynamic data = context.People
        .Join(context.Pets, person => person.Id, Pet => Pet.Pid, (person, pet) => new { Person = person.Name, Pet = pet.Name });
    return View(data);
}

View:
@model dynamic

@foreach(var item in Model)
{
    @(item.Person)<text>,</text>@(item.Pet)<br />
}



其原因是C#的编译器总是将匿名类型编译成internal的,当通过dynamic访问在当前上下文不可见的成员的时候,就会引发异常。问题重现:

using System;
using System.Collections.Generic;
using System.Linq;

namespace Controller
{
    public class Test
    {
        /// <summary>
        /// 模拟匿名对象匿名类
        /// </summary>
        private class Anonymous
        {
            public string Person { get; set; }
            public string Pet { get; set; }
        }

        public dynamic GetValue()
        {
            return new Anonymous();
        }
    }
}

namespace View
{
    using Controller;

    class Program
    {
        static void Main(string[] args)
        {
            dynamic anonymous = new Test().GetValue();
            Console.WriteLine(anonymous.Person);

            Console.ReadKey();
        }
    }
}

以前都用老赵的ToDynamic方法解决,今天在.NET 4.0的System命名空间下看到一个类Tuple,了解后发现用它也可以解决上边的问题:

Controller:
public ActionResult Index()
{
    testContext context = new testContext();
    dynamic data = context.People
        .Join(context.Pets, person => person.Id, Pet => Pet.Pid, (person, pet) => new { Person = person.Name, Pet = pet.Name })
        .ToList().Select(item => Tuple.Create(item.Person, item.Pet));
    return View(data);
}

View:
@model IEnumerable<Tuple<string, string>>

@foreach(var item in Model)
{
    @(item.Item1)<text>,</text>@(item.Item2)<br />
}



参考资料

[1].使用dynamic在ASP.NET MVC中应用匿名ViewModel:http://blog.csdn.net/deboywang/article/details/6627191
[2].当类型为dynamic的视图模型遭遇匿名对象:http://blog.zhaojie.me/2010/05/asp-net-mvc-dynamic-view-model-binding-error-with-anonymous-types.html
[3].当dynamic遭遇匿名对象所造成的问题初步研究结论:http://www.cnblogs.com/Ivony/archive/2010/05/21/1740546.html
[4].Tuple类:http://msdn.microsoft.com/zh-cn/library/System.Tuple(v=vs.100).aspx

评论: 0 | 引用: 0 | 查看次数: 4889
发表评论
登录后再发表评论!