当前位置:编程学习 > asp >>

Asp.Net MVC 项目预编译 View

最近做项目是遇到一个问题,在我们的view中经常遇到一些匿名类型对象,然后在通过RenderPartial输出这些对象。

还是举个例子吧,有3个view Index.cshtml、Test.cshtml、Test2.cshtml

它们的层次结构如图:

 \

它们的代码如下:

Index.cshtml


[csharp]
@{ 
    Layout = null; 
    var obj = new[] { 
    new {name="majiang",age=27}, 
    new {name="luyang",age=26} 
    }; 

 
<!DOCTYPE html> 
 
<html> 
<head> 
    <title>Index</title> 
</head> 
<body> 
    <div> 
        @{ 
               <h2>@(obj.GetType().Assembly.Location)</h2> 
            Html.RenderPartial("Test", obj); 
            Html.RenderPartial("Test2", obj); 
          } 
    </div> 
</body> 
</html> 

@{
    Layout = null;
    var obj = new[] {
    new {name="majiang",age=27},
    new {name="luyang",age=26}
    };
}

<!DOCTYPE html>

<html>
<head>
    <title>Index</title>
</head>
<body>
    <div>
        @{
               <h2>@(obj.GetType().Assembly.Location)</h2>
            Html.RenderPartial("Test", obj);
            Html.RenderPartial("Test2", obj);
          }
    </div>
</body>
</html>
Test.cshtml 和Test2.cshtml

 

[csharp] view plaincopyprint?@{ 
    Layout = null; 
 
    var obj = this.Model; 
    var a =  new {name="majiang",age=27}; 
     
    <h2>@(a.GetType().Assembly.Location)</h2> 
     
    foreach (var item in obj) 
    { 
        <h3>@item.name</h3> 
    <h3>@item.age</h3> 
    } 

@{
    Layout = null;

    var obj = this.Model;
    var a =  new {name="majiang",age=27};
   
    <h2>@(a.GetType().Assembly.Location)</h2>
   
    foreach (var item in obj)
    {
        <h3>@item.name</h3>
    <h3>@item.age</h3>
    }
}
运行结果Test2.cshtml有错误 提示:

 \

为什么在test里面是对的而到了test2就错了,这2个view只是路径不同,对就是路径不同导致生成dll的路径也不同吗?让我们来证实一下

首先把 test2里面的代码修改为:

@{
    Layout = null;

    var obj = this.Model;
    var a = new { name = "majiang", age = 27 };
   
    <h2>@(a.GetType().Assembly.Location)</h2>
   
@*    foreach (var item in obj)
    {
        <h3>@item.name</h3>
    <h3>@item.age</h3>
    }*@
}

运行结果如图:

 \

 

 

很明显test和index在同一目录下,它们生成的匿名类型也在同一个dll中,而test2 不再这一目录中那么生成的匿名类型也不再同一dll中。

为什么会这样了,让我们来看看源代码吧

在BuildManagerCompiledView类的 public void Render(ViewContext viewContext, TextWriter writer)方法中有

 Type type = BuildManager.GetCompiledType(ViewPath);

而BuildManager的定义是:

        internal IBuildManager BuildManager {
            get {
                if (_buildManager == null) {
                    _buildManager = new BuildManagerWrapper();
                }
                return _buildManager;
            }
            set {
                _buildManager = value;
            }
        }

再让我们看看BuildManagerWrapper类


    internal sealed class BuildManagerWrapper : IBuildManager {
        bool IBuildManager.FileExists(string virtualPath) {
            return BuildManager.GetObjectFactory(virtualPath, false) != null;
        }

        Type IBuildManager.GetCompiledType(string virtualPath) {
            return BuildManager.GetCompiledType(virtualPath);
        }

        ICollection IBuildManager.GetReferencedAssemblies() {
            return BuildManager.GetReferencedAssemblies();
        }

        Stream IBuildManager.ReadCachedFile(string fileName) {
            return BuildManager.ReadCachedFile(fileName);
        }

        Stream IBuildManager.CreateCachedFile(string fileName) {
            return BuildManager.CreateCachedFile(fileName);
        }
    }

看来view的编译取决于系统的BuildManager,它既是程序集内部类同时也是密封类要扩展它不太现实。


那么这个如

补充:Web开发 , ASP.Net ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,