MVC里面的generated.cs

把cshtml的文件转换成generated.cs

下载的学习文件中备注generated.cs为自动生成,不能随便更改。找了半天也不知道该怎么自动生成,后来发现原来是需要在 Tools 的 Extensions and Updates下载razor generator.

----------------------------------------------以下内容为转载-------------------------------------------------------------

项目又出问题了!手贱了一下,使用某个工具整理了一下 View 中的内容,不经意之间,将 View 的输出中大小写不小心搞错了,导致输出的内容没有办法正常解析。

这种问题太隐蔽了,下次再遇到怎么办呢?

测试我们的 View ,保证下次不再出现这种问题。

比如说,我们有一个控制器 HomeController.cs 来说,其中包含一个名为 About 的 Action ,它使用 About.cshtml 来呈现最终的输出内容。

About 这个 Action 的定义如下,其中使用了 ViewBag 来传递两个参数到 View 中。

public ActionResult About()
{
    ViewBag.Message = "Your application description page.";

    return View();
}

About.cshtml 的定义如下:

MVC里面的generated.cs
@{
    ViewBag.Title = "About";
}
<h2>@ViewBag.Title.</h2>
<h3>@ViewBag.Message</h3>

<p>Use this area to provide additional information.</p>
MVC里面的generated.cs

 

由于 HTML 内容不容易测试,测试的基本思路是将视图 cshtml 转化为一个代码类,这样我们就可以通过直接执行代码来获取它的输出进行测试了。

 

1. 使用 RazorGenerator 来将 cshtml 转换为代码类

 RazorGenerator 项目现在 GitHub 上 ,原来这个项目在 codeplex 上,在 visualstudiogallery  也有一个分身,现在已经迁移到了 GitHub 上。

在 Visual Studio 中,打开 Tools 的 Extensions and Updates... 菜单。

MVC里面的generated.cs

在弹出的对话框中,输入 Razor Generator 查找这个 Visual Studio 插件,注意要在 online 中查找,在已经安装的插件中可是找不到的。

MVC里面的generated.cs

点击 Download 可以下载并安装。

MVC里面的generated.cs

安装之后,会提示需要重新启动 Visual Studio.

MVC里面的generated.cs

2. 设置工具

在项目中,找到你希望将 cshtml 转化为代码的 View ,比如我们的 About.cshtml 这个视图,选中之后。在属性窗中,设置它的 Custom Tool 为 RazorGenerator,如下所示。

MVC里面的generated.cs

设置之后,你就会看到在 About.cshtml 文件的下面出现了一个新的文件 About.generated.cs 文件,这就是使用这个工具自动生成的代码文件。

MVC里面的generated.cs

这个文件的输出内容如下:

MVC里面的generated.cs
#pragma warning disable 1591
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.34014
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace ASP
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Text;
    using System.Web;
    using System.Web.Helpers;
    using System.Web.Mvc;
    using System.Web.Mvc.Ajax;
    using System.Web.Mvc.Html;
    using System.Web.Routing;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.WebPages;
    
    [System.CodeDom.Compiler.GeneratedCodeAttribute("RazorGenerator", "2.0.0.0")]
    [System.Web.WebPages.PageVirtualPathAttribute("~/Views/Home/About.cshtml")]
    public partial class _Views_Home_About_cshtml : System.Web.Mvc.WebViewPage<dynamic>
    {
        public _Views_Home_About_cshtml()
        {
        }
        public override void Execute()
        {
            
            #line 1 "..\..\Views\Home\About.cshtml"
  
    ViewBag.Title = "About";

            
            #line default
            #line hidden
WriteLiteral("\r\n<h2>");

            
            #line 4 "..\..\Views\Home\About.cshtml"
Write(ViewBag.Title);

            
            #line default
            #line hidden
WriteLiteral(".</h2>\r\n<h3>");

            
            #line 5 "..\..\Views\Home\About.cshtml"
Write(ViewBag.Message);

            
            #line default
            #line hidden
WriteLiteral("</h3>\r\n\r\n<p>Use this area to provide additional information.</p>\r\n");

        }
    }
}
#pragma warning restore 1591
MVC里面的generated.cs

按照项目的说明,默认生成的命名空间应该是项目的命名空间。可以在 Custom Tool Namespace 中指定命名空间。

如果希望所有的视图都生成代码文件,可以在 Nuget 的 Package Manager 控制台窗口中,执行下面的命令来完成。

Enable-RazorGenerator

生成的文件可以在运行时替换掉原来的 cshtml 文件。

3. 测试

在测试项目中,使用 Nuget 添加对 RazorGenerator.Testing 的引用。

MVC里面的generated.cs

安装过程中

MVC里面的generated.cs

安装完成之后。

MVC里面的generated.cs

在我们的测试项目中,添加一个测试,如下所示。

MVC里面的generated.cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using RazorGenerator.Testing;

namespace UnitTestProject2
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestAboutView()
        {
            var view = new ASP._Views_Home_About_cshtml();
            view.ViewBag.Title = "Hello";
            view.ViewBag.Message = "Hello, RazorGenerator";

            var output = view.Render();
            var expected = @"
<h2>About.</h2>
<h3>Hello, RazorGenerator</h3>

<p>Use this area to provide additional information.</p>
";
            Assert.AreEqual(expected, output);
        }
    }
}
MVC里面的generated.cs

编译之后,会看到一个错误提示,程序集的版本不对。说我们的 MVC 项目使用了 4.0.0.1 版本的 System.Web.Mvc,而现在这个项目中的是 3.0.0.1 版本,当然要换成新的了。

Assembly 'ASPNETMVC_Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' uses 'System.Web.Mvc, Version=4.0.0.1, Culture=neutral, PublicKeyToken=31bf3856ad364e35' which has a higher version than referenced assembly 'System.Web.Mvc, Version=3.0.0.1, Culture=neutral, PublicKeyToken=31bf3856ad364e35'

这个很容易,删除原来引用的程序集,添加 4.0.0.1 程序集

MVC里面的generated.cs

重新编译,又报下面的错误。

Assembly 'System.Web.Mvc, Version=4.0.0.1, Culture=neutral, PublicKeyToken=31bf3856ad364e35' uses 'System.Web.WebPages, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' which has a higher version than referenced assembly 'System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'

与上面一样,重新添加 2.0.0.0 版本的 System.Web.Web.Pages 就可以了。

重新编译,终于通过了,运行一下,天哪,没有通过,检查错误原因。

Test method UnitTestProject2.UnitTest1.TestAboutView threw exception: 
System.IO.FileNotFoundException: 未能加载文件或程序集“System.Web.Mvc, Version=3.0.0.1, Culture=neutral, PublicKeyToken=31bf3856ad364e35”或它的某一个依赖项。系统找不到指定的文件。警告: 程序集绑定日志记录被关闭。
要启用程序集绑定失败日志记录,请将注册表值 [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD)设置为 1。
注意: 会有一些与程序集绑定失败日志记录关联的性能损失。

根本就没有执行呀,未能加载文件或称程序集 System.Web.Mvc,Version=3.0.0.1,我们都 4.0.0.1 了,哪里来的 3.0.0.1 呢?添加一个 app.config 文件,加入下面的内容,告诉它直接找我们对应的版本。

两个程序集都指定一下。

MVC里面的generated.cs
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
        <bindingRedirect oldVersion="1.0.0.0-5.2.2.0" newVersion="4.0.0.1"/>
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35"/>
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="2.0.0.0"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>
MVC里面的generated.cs

或者网站项目和测试项目都使用 Nuget 来添加 System.Web.Mvc 的引用,来保证一致性。

现在重新运行一下,终于成功了。

MVC里面的generated.cs