项目又出问题了!手贱了一下,使用某个工具整理了一下 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 的定义如下:

@{
ViewBag.Title = "About";
}
<h2>@ViewBag.Title.</h2>
<h3>@ViewBag.Message</h3> <p>Use this area to provide additional information.</p>

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

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

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

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

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

点击 Download 可以下载并安装。

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

2. 设置工具

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

设置之后,你就会看到在 About.cshtml 文件的下面出现了一个新的文件 About.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

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

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

Enable-RazorGenerator

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

3. 测试

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

安装过程中

安装完成之后。

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

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 项目使用了 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 程序集

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

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 文件,加入下面的内容,告诉它直接找我们对应的版本。

两个程序集都指定一下。

<?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>

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

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

ASP.NET MVC 之 View 测试的更多相关文章

  1. 返璞归真 asp.net mvc (4) - View/ViewEngine

    原文:返璞归真 asp.net mvc (4) - View/ViewEngine [索引页] [源码下载] 返璞归真 asp.net mvc (4) - View/ViewEngine 作者:web ...

  2. ASP.NET MVC 之View

    仅此一文让你明白ASP.NET MVC 之View的显示(仅此一文系列二)   题外话 一周之前写的<仅此一文让你明白ASP.NET MVC原理>受到了广大学习ASP.NET MVC同学的 ...

  3. ASP.NET MVC 中 View 的设计

    1. 前言  感觉有好长时间没有接触View 了,周末闲来无事,翻翻书桌上的书来回顾回顾ASP.NET MVC中View的相关内容. 2. View概述  View 通过应用程序在Action 中返回 ...

  4. 预热ASP.NET MVC 的View

    ASP.NET MVC 的View 预设是Load on Demand(按需加载),也就是说View 第一次要Render 的时候才会去载入跟编译,这个就会造成一个现象,即使Web 应用程式已经完成启 ...

  5. TransactionScope事务处理方法介绍及.NET Core中的注意事项 SQL Server数据库漏洞评估了解一下 预热ASP.NET MVC 的VIEW [AUTOMAPPER]反射自动注册AUTOMAPPER PROFILE

    TransactionScope事务处理方法介绍及.NET Core中的注意事项   作者:依乐祝 原文链接:https://www.cnblogs.com/yilezhu/p/10170712.ht ...

  6. Asp.Net MVC向视图View传值的三种方法

    本文将总结Asp.Net MVC向视图View传值的三种常见的方法: ----------------------------------------------------------------- ...

  7. asp.net mvc同一个view展示多个不同列表思路

    asp.net mvc一个模型一个view容易展示,可是遇到像首页那样,要同时调用好几个不同表的内容一小部分展示时,该怎么是好呢? 下边根据我的测试,用的是mvc access数据测试 先建立一个强类 ...

  8. 仅此一文让你明白ASP.NET MVC 之View的显示(仅此一文系列二)

    题外话 一周之前写的<仅此一文让你明白ASP.NET MVC原理>受到了广大学习ASP.NET MVC同学的欢迎,于是下定决心准备把它写成一个系列,以满足更多求知若渴的同学们.蒋金楠老师已 ...

  9. Asp.net MVC在View里动态捆绑压缩引用的js

    前言 Asp.net MVC 4以上版本多了BundleConfig.RegisterBundles方法,可以把要捆绑的脚本或样式进行捆绑压缩,以减少客户端的请求次数从而提高了客户端的访问速度. 问题 ...

随机推荐

  1. CryptoAPI与openssl数字签名与验证交互

    昨天写过了RSA非对称加密解密的交互方式, 其实数字签名也是RSA非对称加密,只不过用私钥加密的,再加上个hash摘要 CryptoAPI与openssl RSA非对称加密解密(PKCS1 PADDI ...

  2. Value Dispose() cannot be called while doing CreateHandle().

    在backgroundWorker run之前show出了一个窗体_frm. _frmpw = new FrmPleaseWait(); _frmpw.SetMsg("正在请求") ...

  3. (转)WEB第三方打印控件[ASP.NET常用工具]

    本文转载自:http://blog.csdn.net/chz_cslg/article/details/25415347 在B/S模式开发中,打印是个很大的困扰.无论是采用页面直接输出或者引用WORD ...

  4. 从官方下载 Bootstrap 版本 并写 第一个页面

    从官方下载  Bootstrap 版本 页面内容参考自 http://www.cnblogs.com/sanjuantianshu/p/3935120.html bootstrap-3.2.0.zip ...

  5. 【Linux】系统之vmstat&iostat

    Linux系统出现了性能问题,一般我们可以通过top.iostat.free.vmstat等命令来查看初步定位问题. iostat常见用法: $iostat -d -k 1 10 #查看TPS和吞吐量 ...

  6. (四)java程序基本组成

    一个基本的java程序一般包括几个部分,分别是程序所在的包名.程序中用到的其他包的路径.程序的类.类中的方法.变量和字面量. package demo; import java.util.Date; ...

  7. 【转】一道SQL SERVER DateTime的试题

    学习过上一篇SQL SERVER DateTime精度的文章后.再来做一道题. IF ('2011-07-31 00:00:00.000' BETWEEN '2011-07-01' and '2011 ...

  8. final specifier (since C++11)

    Specifies that a virtual function cannot be overridden in a derived class or that a class cannot be  ...

  9. 【SQL Server】系统学习之一:表表达式

    本节讨论的相关内容包括:视图.派生表.CTE.内联表值函数 场景:如果要查询一组数据(例如聚合数据,也就是几个表聚合在一起的数据),这些数据并未在数据库中以表的形式存在. 1.视图:通常用来分解大型的 ...

  10. [JS]深入理解JavaScript系列(4):立即调用的函数表达式

    转自:汤姆大叔的博客 前言 大家学JavaScript的时候,经常遇到自执行匿名函数的代码,今天我们主要就来想想说一下自执行.在详细了解这个之前,我们来谈了解一下"自执行"这个叫法 ...