﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>博客园-Anders Liu的.NET空间</title><link>http://www.cnblogs.com/AndersLiu/</link><description>传播知识源于掌握知识，但又高于掌握知识。我要做一个掌握很多知识的传播知识的人。</description><language>zh-cn</language><lastBuildDate>Fri, 25 Jul 2008 23:33:14 GMT</lastBuildDate><pubDate>Fri, 25 Jul 2008 23:33:14 GMT</pubDate><ttl>60</ttl><item><title>[翻译] ASP.NET MVC Tip #11 – 使用标准的控制器操作名称</title><link>http://www.cnblogs.com/AndersLiu/archive/2008/07/21/asp-net-mvc-tip-11-use-standard-controller-action-names.html</link><dc:creator>Anders Liu</dc:creator><author>Anders Liu</author><pubDate>Mon, 21 Jul 2008 02:26:00 GMT</pubDate><guid>http://www.cnblogs.com/AndersLiu/archive/2008/07/21/asp-net-mvc-tip-11-use-standard-controller-action-names.html</guid><wfw:comment>http://www.cnblogs.com/AndersLiu/comments/1247433.html</wfw:comment><comments>http://www.cnblogs.com/AndersLiu/archive/2008/07/21/asp-net-mvc-tip-11-use-standard-controller-action-names.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cnblogs.com/AndersLiu/comments/commentRss/1247433.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/AndersLiu/services/trackbacks/1247433.html</trackback:ping><description><![CDATA[<p id="nzov" goog_docs_charindex="1">原文地址：<a id="nzov0" href="http://weblogs.asp.net/stephenwalther/archive/2008/06/27/asp-net-mvc-tip-11-use-standard-controller-action-names.aspx" goog_docs_charindex="7">http://weblogs.asp.net/stephenwalther/archive/2008/06/27/asp-net-mvc-tip-11-use-standard-controller-action-names.aspx</a></p>
<p id="nzov1" goog_docs_charindex="127">&nbsp;</p>
<p id="nzov2" goog_docs_charindex="130">摘要：在这个Tip中，Stephen Walther建议你为控制器操作使用标准的名字，这样可以使你的代码对其他开发者更明晰。</p>
<div style="text-align:center">
<script type="text/javascript"><!--
google_ad_client = "pub-0410788977836329";
google_ad_width = 728;
google_ad_height = 90;
google_ad_format = "728x90_as";
google_ad_type = "text_image";
//2007-07-05: cnblogs.com
google_ad_channel = "5389395912";
google_color_border = "336699";
google_color_bg = "FFFFFF";
google_color_link = "0000FF";
google_color_text = "000000";
google_color_url = "008000";
google_ui_features = "rc:0";
//-->
</script>
<script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<p id="hw8a" goog_docs_charindex="194">&nbsp;</p>
<p id="hw8a0" goog_docs_charindex="197">采用命名约定可以使其他开发者——以及你自己将来——更容易阅读你的代码。命名约定还可以为你节省时间，可以避免费力去讨论&#8220;正确的&#8221;命名方式。在这个Tip中，我建议为ASP.NET MVC控制器操作使用标准的名字。</p>
<p id="rw47" goog_docs_charindex="303">&nbsp;</p>
<p id="rw470" goog_docs_charindex="306">下面这个表格列出了控制器操作的标准名字：</p>
<p id="sora" goog_docs_charindex="328">&nbsp;</p>
<div id="w9x_" goog_docs_charindex="331">
<table id="el4e" class="zeroBorder" border="0" cellspacing="0" cellpadding="3" width="100%" goog_docs_charindex="332">
    <tbody id="w9x_0" goog_docs_charindex="333">
        <tr id="w9x_1" goog_docs_charindex="334">
            <td id="w9x_2" goog_docs_charindex="335">操作</td>
            <td id="w9x_3" goog_docs_charindex="339">示例URL</td>
            <td id="w9x_4" goog_docs_charindex="346">说明</td>
        </tr>
        <tr id="w9x_5" goog_docs_charindex="351">
            <td id="w9x_6" goog_docs_charindex="352">Details</td>
            <td id="w9x_7" goog_docs_charindex="361">/Product/Details/5</td>
            <td id="w9x_8" goog_docs_charindex="381">显示一个单独的资源如一条数据库记录。例如，显示Id为5的一个单独的Product。</td>
        </tr>
        <tr id="w9x_9" goog_docs_charindex="425">
            <td id="w9x_10" goog_docs_charindex="426">Index</td>
            <td id="w9x_11" goog_docs_charindex="433">/Product/Index</td>
            <td id="w9x_12" goog_docs_charindex="449">显示一组资源。例如，显示数据库里产品表中的所有产品。</td>
        </tr>
        <tr id="w9x_13" goog_docs_charindex="478">
            <td id="w9x_14" goog_docs_charindex="479">Create</td>
            <td id="w9x_15" goog_docs_charindex="487">/Product/Create</td>
            <td id="w9x_16" goog_docs_charindex="504">显示用于创建一个新资源的表单。例如，显示一个用于创建新产品的表单。</td>
        </tr>
        <tr id="w9x_17" goog_docs_charindex="540">
            <td id="w9x_18" goog_docs_charindex="541">Insert</td>
            <td id="w9x_19" goog_docs_charindex="549">/Product/Insert</td>
            <td id="w9x_20" goog_docs_charindex="566">将一个新资源插入数据库。通常，在完成一次插入后你应该重定向到其它操作。</td>
        </tr>
        <tr id="w9x_21" goog_docs_charindex="604">
            <td id="w9x_22" goog_docs_charindex="605">Edit</td>
            <td id="w9x_23" goog_docs_charindex="611">/Product/Edit/5</td>
            <td id="w9x_24" goog_docs_charindex="628">显示用于编辑一个现有资源的表单。例如，显示一个用于编辑Id为5的产品的表单。</td>
        </tr>
        <tr id="w9x_25" goog_docs_charindex="669">
            <td id="w9x_26" goog_docs_charindex="670">Update</td>
            <td id="w9x_27" goog_docs_charindex="678">/Product/Update/5</td>
            <td id="w9x_28" goog_docs_charindex="697">更新数据库中的现有资源。通常，在完成一次更新后你应该重定向到其它操作。</td>
        </tr>
        <tr id="w9x_29" goog_docs_charindex="735">
            <td id="w9x_30" goog_docs_charindex="736">Destroy</td>
            <td id="w9x_31" goog_docs_charindex="745">/Product/Destroy/5</td>
            <td id="w9x_32" goog_docs_charindex="765">显示一个页面，确认是否真的希望从数据库中删除一个资源。</td>
        </tr>
        <tr id="w9x_33" goog_docs_charindex="795">
            <td id="w9x_34" goog_docs_charindex="796">Delete</td>
            <td id="w9x_35" goog_docs_charindex="804">/Product/Delete/5</td>
            <td id="w9x_36" goog_docs_charindex="823">从数据库中删除一个资源。通常，在完成一次删除后你应该重定向到其它操作。</td>
        </tr>
        <tr id="w9x_37" goog_docs_charindex="861">
            <td id="w9x_38" goog_docs_charindex="862">Login</td>
            <td id="w9x_39" goog_docs_charindex="869">/Home/Login</td>
            <td id="w9x_40" goog_docs_charindex="882">显示一个登录表单。</td>
        </tr>
        <tr id="w9x_41" goog_docs_charindex="894">
            <td id="w9x_42" goog_docs_charindex="895">Logout</td>
            <td id="w9x_43" goog_docs_charindex="903">/Home/Logout</td>
            <td id="w9x_44" goog_docs_charindex="917">注销一个用户。通常，在完成一次注销后你应该重定向到其它操作。</td>
        </tr>
        <tr id="w9x_45" goog_docs_charindex="950">
            <td id="w9x_46" goog_docs_charindex="951">Authenticate</td>
            <td id="w9x_47" goog_docs_charindex="965">/Home/Authenticate</td>
            <td id="w9x_48" goog_docs_charindex="985">验证一对用户名和密码。通常，在完成一次验证后你应该重定向到其它操作。</td>
        </tr>
    </table>
</div>
<p id="v:qu" goog_docs_charindex="1025"><br id="w9x_49" goog_docs_charindex="1026" />
我的这些操作名字（非常粗略）是基于Adam Tybor在其MvcContrib项目的Simply Restful Route Handler中使用的命名约定的。该项目位于：</p>
<p id="v:qu0" goog_docs_charindex="1114">&nbsp;</p>
<p id="v:qu1" goog_docs_charindex="1117"><a id="jn13" href="http://www.codeplex.com/MVCContrib/Wiki/View.aspx?title=SimplyRestfulRouting&amp;referringTitle=Documentation" goog_docs_charindex="1118">http://www.codeplex.com/MVCContrib/Wiki/View.aspx?title=SimplyRestfulRouting&amp;referringTitle=Documentation</a></p>
<p id="or_6" goog_docs_charindex="1226">&nbsp;</p>
<p id="or_60" goog_docs_charindex="1229">然而，Adam Tybor的约定和我这里建议的有着显著的不同。下面我来介绍一下二者的区别。</p>
<p id="uweq" goog_docs_charindex="1276">&nbsp;</p>
<p id="uweq0" goog_docs_charindex="1279">首先，Adam Tybor利用不同的HTTP谓词来指出要执行那个控制器操作（他有&#8220;REST癖&#8221;，he is being a REST purist）。例如，Adam Tybor建议同一个URL既用于删除也用于更新一个资源：</p>
<p id="gl4k" goog_docs_charindex="1392">&nbsp;</p>
<p id="gl4k0" goog_docs_charindex="1395">/Product/34</p>
<p id="mmac" goog_docs_charindex="1408">&nbsp;</p>
<p id="mmac0" goog_docs_charindex="1411">当使用HTTP PUT请求该URL时，将更新一条现有记录。当使用HTTP DELETE请求相同的URL时，将删除一条现有记录。Adam Tybor提出的原因是有意义的。他的建议和这些HTTP谓词的目的是统一的。然而，Adam Tybor得难以不能和默认的ASP.NET MVC路由一起工作。因此，我建议你在进行删除和更新时使用明确的URL：</p>
<p id="c__f" goog_docs_charindex="1583">&nbsp;</p>
<p id="c__f0" goog_docs_charindex="1586">/Product/Update/34</p>
<p id="c__f1" goog_docs_charindex="1606">/Product/Delete/34</p>
<p id="cu.b" goog_docs_charindex="1626">&nbsp;</p>
<p id="cu.b0" goog_docs_charindex="1629">如果你使用这些命名约定，你将可以使用默认的ASP.NET MVC路由表。</p>
<p id="q:0t" goog_docs_charindex="1667">&nbsp;</p>
<p id="q:0t0" goog_docs_charindex="1670">我这里建议的控制器操作命名约定和我所见过的其他命名约定之间的另外一个重要区别在于，为创建一个新的资源这样一个操作所取的名字。我见过在创建新的资源时有人用过下面这样的操作名字：</p>
<p id="paxh" goog_docs_charindex="1759">&nbsp;</p>
<p id="paxh0" goog_docs_charindex="1762">/Product/New</p>
<p id="paxh1" goog_docs_charindex="1776">/Product/Create</p>
<p id="s02:" goog_docs_charindex="1793">&nbsp;</p>
<p id="s02:0" goog_docs_charindex="1796">通常，New操作用于显示用于创建新资源的表单，而Create操作实际执行数据库插入操作。</p>
<p id="ed92" goog_docs_charindex="1842">&nbsp;</p>
<p id="ed920" goog_docs_charindex="1845">问题在于使用New作为操作名字可能会和C#以及Visual Basic .NET关键字冲突。当在Visual Basic .NET应用程序中创建一个名为New的控制器操作时，您必须总要记得将其名字转义为[New]。持续地转义一个名字很快就会变得枯燥，而且对于那些不理解这个方括号的含义的人来说，这样会引起混淆。因此，我建议使用Create和Insert对来代替New和Create对。</p>
<p id="n3hr" goog_docs_charindex="2039">&nbsp;</p>
<p id="n3hr0" goog_docs_charindex="2042">你可能已经注意到了，我在试图让操作和（实际）执行的数据库操作中的SQL语句名字对应起来。因此，下面的URL应该是用于显示表单的：</p>
<p id="eni7" goog_docs_charindex="2108">&nbsp;</p>
<p id="eni70" goog_docs_charindex="2111">/Product/Create</p>
<p id="eni71" goog_docs_charindex="2128">/Product/Edit/1</p>
<p id="eni72" goog_docs_charindex="2145">/Product/Destroy/1</p>
<p id="eni73" goog_docs_charindex="2165">&nbsp;</p>
<p id="eni74" goog_docs_charindex="2168">而下面的URL应该是用于执行数据库操作的：</p>
<p id="eni75" goog_docs_charindex="2191">&nbsp;</p>
<p id="eni76" goog_docs_charindex="2194">/Product/Insert</p>
<p id="eni77" goog_docs_charindex="2211">/Product/Update/1</p>
<p id="eni78" goog_docs_charindex="2230">/Product/Delete/1</p>
<p id="zksd" goog_docs_charindex="2249">&nbsp;</p>
<p id="zksd0" goog_docs_charindex="2252">对命名约定提出建议总是有风险的，因为开发者对于如何正确地取名总是具有强烈的个人意见。然而，我希望这篇Tip能够作为你开发一款命名约定的起点。</p>
<p goog_docs_charindex="2252">&nbsp;</p>
<p goog_docs_charindex="2252">------</p>
<p goog_docs_charindex="2252">&nbsp;</p>
<p goog_docs_charindex="2252">本文没有代码。广告还是.NET正则表达式库，<a href="http://regex-lib.net">http://regex-lib.net</a>。</p><img src ="http://www.cnblogs.com/AndersLiu/aggbug/1247433.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41307/" target="_blank">[新闻]金山:360的免费杀毒只能是短期行为</a>]]></description></item><item><title>[翻译] ASP.NET MVC CodePlex Preview 4 Release Notes</title><link>http://www.cnblogs.com/AndersLiu/archive/2008/07/18/ASP-NET-MVC-CodePlex-Preview-4-Release-Notes.html</link><dc:creator>Anders Liu</dc:creator><author>Anders Liu</author><pubDate>Fri, 18 Jul 2008 08:25:00 GMT</pubDate><guid>http://www.cnblogs.com/AndersLiu/archive/2008/07/18/ASP-NET-MVC-CodePlex-Preview-4-Release-Notes.html</guid><wfw:comment>http://www.cnblogs.com/AndersLiu/comments/1246195.html</wfw:comment><comments>http://www.cnblogs.com/AndersLiu/archive/2008/07/18/ASP-NET-MVC-CodePlex-Preview-4-Release-Notes.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cnblogs.com/AndersLiu/comments/commentRss/1246195.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/AndersLiu/services/trackbacks/1246195.html</trackback:ping><description><![CDATA[<body>
<h1 class="al-title">ASP.NET MVC CodePlex Preview 4 Release Notes</h1>
<div class="al-copy">
 <p>您可以从这里下载到该文档：<a href="http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=15389" target="_blank">http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=15389</a>。</p>
 <p>翻译：<a href="http://andersliu.cnblogs.com" title="Anders Liu">Anders Liu</a></p>
</div>
<div class="al-summary">
 <p>摘要：本文档描述了ASP.NET MVC框架的Preview 3与目前的CodePlex Preview 4之间的差别。还介绍了要运行新的发布版，你必须对现有的MVC应用程序进行的修改。</p>
</div>
<div class="al-adc">
<script type="text/javascript"><!--
google_ad_client = "pub-0410788977836329";
google_ad_width = 728;
google_ad_height = 90;
google_ad_format = "728x90_as";
google_ad_type = "text_image";
//2007-07-05: cnblogs.com
google_ad_channel = "5389395912";
google_color_border = "336699";
google_color_bg = "FFFFFF";
google_color_link = "0000FF";
google_color_text = "000000";
google_color_url = "008000";
google_ui_features = "rc:0";
//-->
</script>
<script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<p class="al-p">
 <ul class="al-ul">
  <li><a href="#1">简介</a></li>
  <li><a href="#2">What&#8217;s New</a>
   <ul>
    <li><a href="#2.1">默认项目模板中的简单成员资格特性</a></li>
    <li><a href="#2.2">用于授权和异常处理的过滤器类型</a></li>
    <li><a href="#2.3">输出缓存过滤器</a></li>
    <li><a href="#2.4">ASP.NET AJAX的变化</a></li>
    <li><a href="#2.5">路由的命名空间</a></li>
    <li><a href="#2.6">TempData的增强可测试性接口</a></li>
    <li><a href="#2.7">ActionInvoker可扩展改进</a></li>
   </ul></li>
 <li><a href="#3">ViewDataDictionary</a></li>
 <li><a href="#4">MVC的未来</a></li>
 <li><a href="#5">将现有的Preview3应用程序升级到Preview 4 CodePlex Release</a></li>
 <li><a href="#6">已知问题</a></li>
 </ul>
</p>
<h2 class="al-t1"><a name="1">简介</a></h2>
<p class="al-p">CodePlex Preview 4的发布包含了很多新的特性，并对默认项目模板进行了修改。对默认项目模板进行修改的目的是帮助启动最常见的应用程序构建场景。很多新特性都集中在简单的AJAX场景上。</p>
<h2 class="al-t1"><a name="2">What&#8217;s New</a></h2>
<p class="al-p">这一部分介绍了该发布版中新的和修改过的特性。</p>
<h3 class="al-t2"><a name="2.1">默认项目模板中的简单成员资格特性</a></h3>
<p class="al-p">很多Web应用程序都需要某种形式的用户验证。该发布版在默认项目模板中包含了一个AccountController类，用于处理下面这些用户操作：</p>
<ul class="al-dotul">
 <li>登录</li>
 <li>注销</li>
 <li>注册</li>
 <li>修改密码</li>
</ul>
<p class="al-p">默认项目模板的Web.config文件中包含了对<span class="al-inline-code">MembershipProvider</span>类的配置。这意味着当首次访问成员资格特性时，ASP.NET会自动创建一个SQL Server Express Edition成员资格数据库。你可以将SQL Server Express Edition数据库转换为SQL Server数据库，或修改Web.config文件中的连接字符串，使其指向一个现有的包含成员资格表的数据库。</p>
<p class="al-p">默认模板中还包含Microsoft ASP.NET AJAX脚本文件的一个副本。我们一直在持续地为MVC版的<span class="al-inline-code">ScriptManager</span>控件进行工作；例如，我们使注册包含在嵌入资源中的脚本更加容易。然而，这些改进没有包含在这个发布版中。</p>
<h3 class="al-t2"><a name="2.2">用于授权和异常处理的过滤器类型</a></h3>
<p class="al-p">该发布版包含两种新的过滤器类型——授权过滤器和异常过滤器。尽管操作过滤器依然是最常见的过滤器类型，但我们希望提供能够在任意或者所有操作过滤器之前运行的过滤器，而不管过滤器的作用域。这样可以防止某些情形的出现，如在<span class="al-inline-code">Authorization</span>过滤器之前执行<span class="al-inline-code">OutputCache</span>过滤器，从而导致骗取授权。</p>
<p class="al-p">为了支持新的过滤器类型，加入或修改了下列特性：</p>
<ul class="al-dotul">
 <li>新的<span class="al-inline-code">IAuthorizationFilter</span>和<span class="al-inline-code">IExceptionFilter</span>接口。授权过滤器可以确保在所有其他操作过滤器之前运行。每个异常过滤器都会执行，即便是某个过滤器指明它已经处理了请求。这有助于记录和处理异常。</li>
 <li><span class="al-inline-code">AuthorizeAttribute</span>类。这是<span class="al-inline-code">IAuthorizationFilter</span>的默认的具体实现。用于确保操作方法的安全。</li>
 <li><span class="al-inline-code">HandleErrorAttribute</span>类。这是<span class="al-inline-code">IExceptionFilter</span>的默认的具体实现。用于处理异常并指定在发生异常时呈现哪个视图。</li>
 <li>新的<span class="al-inline-code">FilterAttribute</span>基类。我们和新的过滤器类型一起引入了新的基类，这对所有过滤器特性都是有用的。</li>
</ul>
<h3 class="al-t2"><a name="2.3">输出缓存过滤器</a></h3>
<p class="al-p"><span class="al-inline-code">OutputCacheAttribute</span>类是一个新的操作过滤器，用于使用内建的ASP.NET输出缓存来缓存操作方法的输出。</p>
<div class="al-ins">
 <p class="al-ins-title">注意</p>
 <p class="al-p">在该发布版中，在Medium信任级别下为输出缓存过滤器设置<span class="al-inline-code">CacheProfile</span>属性会抛出一个异常。该问题会在未来的发布版中解决。</p>
</div>
<h3 class="al-t2"><a name="2.4">ASP.NET AJAX的变化</a></h3>
<p class="al-p">添加了下面的AJAX辅助方法。它们使用<span class="al-inline-code">AjaxOptions</span>类来指定异步操作的选项。</p>
<ul class="al-dotul">
 <li><span class="al-inline-code">ActionLink</span>。该方法呈现一个指向某操作方法的锚标签。当单击该链接时，会异步地调用操作方法。该辅助方法的典型应用是通过指定<span class="al-inline-code">AjaxOptions.UpdateTargetId</span>属性获取响应并更新DOM元素。</li>
 <li><span class="al-inline-code">Form</span>。该方法呈现一个可以异步提交的HTML表单。该辅助方法的典型应用是提交表单，和<span class="al-inline-code">ActionLink</span>类似，通过指定<span class="al-inline-code">AjaxOptions.UpdateTargetId</span>属性来获取响应并更新DOM元素。</li>
</ul>
<p class="al-p">我们将持续为ASP.NET MVC增强AJAX特性。这里提到的特性只是一个初级版本，我们希望在将来的发布版中能提供更强的特性。</p>
<h3 class="al-t2"><a name="2.5">路由的命名空间</a></h3>
<p class="al-p">在ASP.NET MVC之前的预览版中，框架会扫描所有程序集中的类型，以便找到控制器实现。然而，这样做偶尔会抛出异常，如某个类型是从一个尚未加载的程序集中的某个类型继承而来的，则框架在反射该类型时就会出错。</p>
<p class="al-p">在这个发布中，我们提供了一种途径，能够为框架指定在尝试加载控制器类型时去检查哪些命名空间，这需要使用<span class="al-inline-code">ControllerBuilder</span>类的<span class="al-inline-code">DefaultNamespaces</span>属性。下面的示例展示了如何为解析控制器加载命名空间。</p>
<div class="al-ins">
  <textarea name="al-code" class="C#" cols="60" rows="25">
void Application_Start(object sender, EventArgs e) {
    ControllerBuilder.Current.DefaultNamespaces.Add("MyApp.Controllers");
    ControllerBuilder.Current.DefaultNamespaces.Add("MyApp.Blog.Controllers");
    ControllerBuilder.Current.DefaultNamespaces.Add("ThirdPartyApp.Controllers");
    // ...
}</textarea>
</div>
<p class="al-p">你也可以依次为每个路由指定命名空间。（在该发布版中，你还不能使用<span class="al-inline-code">MapRoute</span>扩展方法来做这件事。）下面的例子展示了如何为一个路由指定命名空间。</p>
<div class="al-ins">
 <textarea name="al-code" class="C#" cols="60" rows="25">
var dataTokens = new RouteValueDictionary();
dataTokens.Add("namespaces", new HashSet<string>(
              new string[] {
                "MyApp.Blog.Controllers", 
                "MyApp.Forum.Controllers", 
                "MyApp.Controllers"
              }));
routes.Add(
  new Route("ns/{controller}/{action}/{id}", new MvcRouteHandler()) {
      Defaults = new RouteValueDictionary(new {
          action = "Index",
          id = (string)null
      }),
      DataTokens = dataTokens
});
</textarea>
</div>
<h3 class="al-t2"><a name="2.6">TempData的增强可测试性接口</a></h3>
<p class="al-p">在该发布版中，我们改进了可测试性，你可以使用会话Cookie而不是会话状态。添加了一个新的<span class="al-inline-code">ITempDataProvider</span>接口。默认情况下，控制器通过<span class="al-inline-code">SessionStateTempDataProvider</span>来访问会话状态，但现在可以实现其他的提供程序了。</p>
<h3 class="al-t2"><a name="2.7">ActionInvoker可扩展改进</a></h3>
<p class="al-p">添加了新的虚拟方法，在高级场景里你可以扩展调用器。下面的表格列出了新的方法。</p>
<table class="al-table">
 <tr><th>方法</th><th>说明</th></tr>
 <tr><td><span class="al-inline-code">GetFiltersForActionMethod</span></td><td>返回操作方法上的所有过滤器（授权、操作和异常过滤器）。</td></tr>
 <tr><td><span class="al-inline-code">InvokeActionResultWithFilters</span></td><td>在操作方法返回的<span class="al-inline-code">ActionResult</span>对象上调用<span class="al-inline-code">ExecuteResult</span>方法，以及应用于该操作方法的所有结果过滤器。</td></tr>
 <tr><td><span class="al-inline-code">InvokeAuthorizationFilters</span></td><td>调用应用于操作方法上的授权过滤器。</td></tr>
 <tr><td><span class="al-inline-code">InvokeExceptionFilters</span></td><td>调用应用于操作方法上的异常过滤器。</td></tr>
</table>
<h2 class="al-t1"><a name="3">ViewDataDictionary</a></h2>
<p class="al-p">我们对<span class="al-inline-code">ViewDataDictionary</span>进行了少许修改，将其索引器修改为一般索引器，并添加了<span class="al-inline-code">Eval</span>方法，用于对模型进行求值。</p>
<h2 class="al-t1"><a name="4">MVC的未来</a></h2>
<p class="al-p">ASP.NET MVC团队在日常的开发过程中，为很多特性建立了原型。这些特性有些会包含在RTM发布版中。如果没有包含进去，则可能会包含在未来的完整发布版中。我们将这些特性中的很多都放在了一个单独的MVC Futures项目中了。你会注意到项目模板包含并引用了一个名为<span class="al-inline-code">Microsoft.Web.Mvc.dll</span>的程序集，这就是MVC Futures项目的编译形式。</p>
<p class="al-p">注意<span class="al-inline-code">ComponentController</span>和<span class="al-inline-code">RenderComponent</span>方法已经被替换成了MVC Futures项目中定义的<span class="al-inline-code">RenderAction</span>方法。<span class="al-inline-code">RenderAction</span>与普通的控制器协作，而不是特定的<span class="al-inline-code">ComponentController</span>对象。</p>
<p class="al-p">对于该发布版，MVC Futures程序集（<span class="al-inline-code">Microsoft.Web.Mvc.dll</span>）被包含在了项目模板中，但在Beta和RTM发布版中就不会这样了。</p>
<h2 class="al-t1"><a name="5">将现有的Preview3应用程序升级到Preview 4 CodePlex Release</a></h2>
<p class="al-p">这一部分介绍了要想使使用Preview 3发布版创建的ASP.NET MVC应用程序能够运行在Preview 4发布版上，必须要对应用程序进行的修改。</p>
<ul class="al-dotul">
 <li>更新对下列程序集的引用，使其指向新的Preview 4版本的程序集：
  <ul class="al-dotul">
   <li><span class="al-inline-code">System.Web.Abstractions</span></li>
   <li><span class="al-inline-code">System.Web.Routing</span></li>
   <li><span class="al-inline-code">System.Web.Mvc</span></li>
  </ul>
  <p class="al-p">默认情况下，这程序集位于下面的文件夹中：</p>
  <p class="al-p">%ProgramFiles% \Microsoft ASP.NET\ASP.NET MVC CodePlex Preview 4</p>
 </li>
 <li>由于操作过滤器API有了些许改变，因此如果你编写了自定义的操作过滤器，你需要更新你的代码，匹配新的签名。</li>
 <li>为了利用模板中的一些变化，你可能需要将模板的变化复制到你的项目中。</li>
</ul>
<h2 class="al-t1"><a name="6">已知问题</a></h2>
<ul class="al-dotul">
 <li>在Medium信任下，在<span class="al-inline-code">OutputCache</span>过滤器上设置<span class="al-inline-code">CacheProfile</span>属性会抛出异常。</li>
 <li>注意如果要在Visual Studio 2008速成版中使用ASP.NET MVC，你需要安装Visual Studio 2008 Express Edition SP1，位于：<a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=BDB6391C-05CA-4036-9154-6DF4F6DEBD14&displaylang=en" target="_blank">http://www.microsoft.com/downloads/details.aspx?FamilyId=BDB6391C-05CA-4036-9154-6DF4F6DEBD14&displaylang=en</a>。与此相关的更多信息，请查看ScottGu的博客主题：<a href="http://weblogs.asp.net/scottgu/archive/2008/06/01/asp-net-mvc-support-with-visual-web-developer-2008-express.aspx" target="_blank">http://weblogs.asp.net/scottgu/archive/2008/06/01/asp-net-mvc-support-with-visual-web-developer-2008-express.aspx</a>。</li>
</ul>
<script src="http://tools.xpus.net/dpsh-1.5.1/Scripts/shCore.js"></script>
<script src="http://tools.xpus.net/dpsh-1.5.1/Scripts/shBrushCSharp.js"></script>
<script src="http://tools.xpus.net/dpsh-1.5.1/Scripts/shBrushXml.js"></script>
<script language="javascript"> 
dp.SyntaxHighlighter.HighlightAll('al-code'); 
</script><img src ="http://www.cnblogs.com/AndersLiu/aggbug/1246195.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41306/" target="_blank">[新闻]江民科技回应杀毒软件免费说 没病不能乱吃药</a>]]></description></item><item><title>[翻译] ASP.NET MVC Tip #10 - 防止URL操作攻击</title><link>http://www.cnblogs.com/AndersLiu/archive/2008/07/17/prevent-url-manipulation-attacks.html</link><dc:creator>Anders Liu</dc:creator><author>Anders Liu</author><pubDate>Thu, 17 Jul 2008 04:35:00 GMT</pubDate><guid>http://www.cnblogs.com/AndersLiu/archive/2008/07/17/prevent-url-manipulation-attacks.html</guid><wfw:comment>http://www.cnblogs.com/AndersLiu/comments/1245104.html</wfw:comment><comments>http://www.cnblogs.com/AndersLiu/archive/2008/07/17/prevent-url-manipulation-attacks.html#Feedback</comments><slash:comments>10</slash:comments><wfw:commentRss>http://www.cnblogs.com/AndersLiu/comments/commentRss/1245104.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/AndersLiu/services/trackbacks/1245104.html</trackback:ping><description><![CDATA[摘要: 原文地址：http://weblogs.asp.net/stephenwalther/archive/2008/06/26/prevent-url-manipulation-attacks.aspx摘要：在这个Tip中，Stephen Walther介绍了黑客如何通过操作URL从ASP.NET MVC网站中窃取敏感信息。Stephen Walther还探讨了如何构建单元测试来防止这类攻击。在一个网&nbsp;&nbsp;<a href='http://www.cnblogs.com/AndersLiu/archive/2008/07/17/prevent-url-manipulation-attacks.html'>阅读全文</a><img src ="http://www.cnblogs.com/AndersLiu/aggbug/1245104.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41305/" target="_blank">[新闻]WCG2008中国区总决赛打响</a>]]></description></item><item><title>[翻译] ASP.NET MVC Tip #9 – 创建GridView视图用户控件</title><link>http://www.cnblogs.com/AndersLiu/archive/2008/07/17/asp-net-mvc-tip-9-create-a-gridview-view-user-control.html</link><dc:creator>Anders Liu</dc:creator><author>Anders Liu</author><pubDate>Thu, 17 Jul 2008 03:38:00 GMT</pubDate><guid>http://www.cnblogs.com/AndersLiu/archive/2008/07/17/asp-net-mvc-tip-9-create-a-gridview-view-user-control.html</guid><wfw:comment>http://www.cnblogs.com/AndersLiu/comments/1245057.html</wfw:comment><comments>http://www.cnblogs.com/AndersLiu/archive/2008/07/17/asp-net-mvc-tip-9-create-a-gridview-view-user-control.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnblogs.com/AndersLiu/comments/commentRss/1245057.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/AndersLiu/services/trackbacks/1245057.html</trackback:ping><description><![CDATA[摘要: 原文地址：http://weblogs.asp.net/stephenwalther/archive/2008/06/25/asp-net-mvc-tip-9-create-a-gridview-view-user-control.aspx摘要：在这个Tip中，Stephen Walther向你展示了如何创建一个ASP.NET MVC视图用户控件，它能接受一组数据库记录，并自动在一个HTML表格中&nbsp;&nbsp;<a href='http://www.cnblogs.com/AndersLiu/archive/2008/07/17/asp-net-mvc-tip-9-create-a-gridview-view-user-control.html'>阅读全文</a><img src ="http://www.cnblogs.com/AndersLiu/aggbug/1245057.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41305/" target="_blank">[新闻]WCG2008中国区总决赛打响</a>]]></description></item><item><title>[翻译] ASP.NET MVC Tip #8 – 创建ASP.NET MVC GridView辅助方法</title><link>http://www.cnblogs.com/AndersLiu/archive/2008/07/12/asp-net-mvc-tip-8-create-an-asp-net-mvc-gridview-helper-method.html</link><dc:creator>Anders Liu</dc:creator><author>Anders Liu</author><pubDate>Sat, 12 Jul 2008 09:27:00 GMT</pubDate><guid>http://www.cnblogs.com/AndersLiu/archive/2008/07/12/asp-net-mvc-tip-8-create-an-asp-net-mvc-gridview-helper-method.html</guid><wfw:comment>http://www.cnblogs.com/AndersLiu/comments/1241495.html</wfw:comment><comments>http://www.cnblogs.com/AndersLiu/archive/2008/07/12/asp-net-mvc-tip-8-create-an-asp-net-mvc-gridview-helper-method.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnblogs.com/AndersLiu/comments/commentRss/1241495.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/AndersLiu/services/trackbacks/1241495.html</trackback:ping><description><![CDATA[摘要: 在这个Tip中，你将学到如何扩展ASP.NET MVC框架，创建一个新的辅助方法，可以为数据库数据显示一个HTML表格。&nbsp;&nbsp;<a href='http://www.cnblogs.com/AndersLiu/archive/2008/07/12/asp-net-mvc-tip-8-create-an-asp-net-mvc-gridview-helper-method.html'>阅读全文</a><img src ="http://www.cnblogs.com/AndersLiu/aggbug/1241495.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41304/" target="_blank">[新闻]新型的编程语言:eC</a>]]></description></item><item><title>[翻译] ASP.NET MVC Tip #7 – 使用Html.Encode避免JavaScript注入攻击</title><link>http://www.cnblogs.com/AndersLiu/archive/2008/07/12/asp-net-mvc-tip-7-prevent-javascript-injection-attacks-with-html-encode.html</link><dc:creator>Anders Liu</dc:creator><author>Anders Liu</author><pubDate>Sat, 12 Jul 2008 01:37:00 GMT</pubDate><guid>http://www.cnblogs.com/AndersLiu/archive/2008/07/12/asp-net-mvc-tip-7-prevent-javascript-injection-attacks-with-html-encode.html</guid><wfw:comment>http://www.cnblogs.com/AndersLiu/comments/1241284.html</wfw:comment><comments>http://www.cnblogs.com/AndersLiu/archive/2008/07/12/asp-net-mvc-tip-7-prevent-javascript-injection-attacks-with-html-encode.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnblogs.com/AndersLiu/comments/commentRss/1241284.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/AndersLiu/services/trackbacks/1241284.html</trackback:ping><description><![CDATA[摘要: 在这个Tip中，你将了解到JavaScript注入攻击可能会比你想象的更加严重。Stephen Walther展示了如何使用JavaScript注入攻击来在一个ASP.NET MVC站点上干些大大的坏事，并解释了如何通过一种简单的方式来防止这种攻击。&nbsp;&nbsp;<a href='http://www.cnblogs.com/AndersLiu/archive/2008/07/12/asp-net-mvc-tip-7-prevent-javascript-injection-attacks-with-html-encode.html'>阅读全文</a><img src ="http://www.cnblogs.com/AndersLiu/aggbug/1241284.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41304/" target="_blank">[新闻]新型的编程语言:eC</a>]]></description></item><item><title>[翻译] ASP.NET MVC Tip #6 – 提交表单后如何进行重定向</title><link>http://www.cnblogs.com/AndersLiu/archive/2008/07/12/asp-net-mvc-tip-6-call-redirecttoaction-after-submitting-a-form.html</link><dc:creator>Anders Liu</dc:creator><author>Anders Liu</author><pubDate>Sat, 12 Jul 2008 01:24:00 GMT</pubDate><guid>http://www.cnblogs.com/AndersLiu/archive/2008/07/12/asp-net-mvc-tip-6-call-redirecttoaction-after-submitting-a-form.html</guid><wfw:comment>http://www.cnblogs.com/AndersLiu/comments/1241279.html</wfw:comment><comments>http://www.cnblogs.com/AndersLiu/archive/2008/07/12/asp-net-mvc-tip-6-call-redirecttoaction-after-submitting-a-form.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/AndersLiu/comments/commentRss/1241279.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/AndersLiu/services/trackbacks/1241279.html</trackback:ping><description><![CDATA[摘要: 在这个Tip中，Stephen Walther介绍了当提交表单后如需重定向，为何需要调用RedirectToAction方法进行重定向，而不是直接返回一个视图。&nbsp;&nbsp;<a href='http://www.cnblogs.com/AndersLiu/archive/2008/07/12/asp-net-mvc-tip-6-call-redirecttoaction-after-submitting-a-form.html'>阅读全文</a><img src ="http://www.cnblogs.com/AndersLiu/aggbug/1241279.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41304/" target="_blank">[新闻]新型的编程语言:eC</a>]]></description></item><item><title>[翻译] ASP.NET MVC Tip #5 – 创建共享视图</title><link>http://www.cnblogs.com/AndersLiu/archive/2008/07/10/asp-net-mvc-tip-5-create-shared-views.html</link><dc:creator>Anders Liu</dc:creator><author>Anders Liu</author><pubDate>Thu, 10 Jul 2008 14:03:00 GMT</pubDate><guid>http://www.cnblogs.com/AndersLiu/archive/2008/07/10/asp-net-mvc-tip-5-create-shared-views.html</guid><wfw:comment>http://www.cnblogs.com/AndersLiu/comments/1240291.html</wfw:comment><comments>http://www.cnblogs.com/AndersLiu/archive/2008/07/10/asp-net-mvc-tip-5-create-shared-views.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cnblogs.com/AndersLiu/comments/commentRss/1240291.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/AndersLiu/services/trackbacks/1240291.html</trackback:ping><description><![CDATA[摘要: 在这个Tip中，Stephen Walther介绍了如何为控制器action创建共享视图。共享视图可以用于多个控制器。本文Stephen Walther介绍的是如何为显示和编辑数据库数据来创建共享视图。&nbsp;&nbsp;<a href='http://www.cnblogs.com/AndersLiu/archive/2008/07/10/asp-net-mvc-tip-5-create-shared-views.html'>阅读全文</a><img src ="http://www.cnblogs.com/AndersLiu/aggbug/1240291.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41303/" target="_blank">[新闻]免费的BitDefender能复制卡巴斯基的成功吗?</a>]]></description></item><item><title>[翻译] ASP.NET MVC Tip #4 - 创建自定义数据控制器基类</title><link>http://www.cnblogs.com/AndersLiu/archive/2008/07/08/asp-net-mvc-tip-4-create-a-custom-data-controller-base-class.html</link><dc:creator>Anders Liu</dc:creator><author>Anders Liu</author><pubDate>Tue, 08 Jul 2008 03:28:00 GMT</pubDate><guid>http://www.cnblogs.com/AndersLiu/archive/2008/07/08/asp-net-mvc-tip-4-create-a-custom-data-controller-base-class.html</guid><wfw:comment>http://www.cnblogs.com/AndersLiu/comments/1238037.html</wfw:comment><comments>http://www.cnblogs.com/AndersLiu/archive/2008/07/08/asp-net-mvc-tip-4-create-a-custom-data-controller-base-class.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.cnblogs.com/AndersLiu/comments/commentRss/1238037.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/AndersLiu/services/trackbacks/1238037.html</trackback:ping><description><![CDATA[摘要: 在这个Tip中，你将学到如何创建一个自定义控制器基类，让它能够为常见的数据库操作暴露一系列acton，如显示、插入、更新和删除数据。&nbsp;&nbsp;<a href='http://www.cnblogs.com/AndersLiu/archive/2008/07/08/asp-net-mvc-tip-4-create-a-custom-data-controller-base-class.html'>阅读全文</a><img src ="http://www.cnblogs.com/AndersLiu/aggbug/1238037.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41301/" target="_blank">[新闻]DNS漏洞攻击代码已经公布 危险迫在眉睫</a>]]></description></item><item><title>[翻译] ASP.NET MVC Tip #3 – 在单元测试时提供明确的视图名字</title><link>http://www.cnblogs.com/AndersLiu/archive/2008/07/06/asp-net-mvc-tip-3-provide-explicit-view-names-when-unit-testing.html</link><dc:creator>Anders Liu</dc:creator><author>Anders Liu</author><pubDate>Sun, 06 Jul 2008 02:33:00 GMT</pubDate><guid>http://www.cnblogs.com/AndersLiu/archive/2008/07/06/asp-net-mvc-tip-3-provide-explicit-view-names-when-unit-testing.html</guid><wfw:comment>http://www.cnblogs.com/AndersLiu/comments/1236813.html</wfw:comment><comments>http://www.cnblogs.com/AndersLiu/archive/2008/07/06/asp-net-mvc-tip-3-provide-explicit-view-names-when-unit-testing.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cnblogs.com/AndersLiu/comments/commentRss/1236813.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/AndersLiu/services/trackbacks/1236813.html</trackback:ping><description><![CDATA[<p id="qfzq" goog_docs_charindex="1">原文地址：<a id="qfzq0" href="http://weblogs.asp.net/stephenwalther/archive/2008/06/17/asp-net-mvc-tip-3-provide-explicit-view-names-when-unit-testing.aspx" goog_docs_charindex="7">http://weblogs.asp.net/stephenwalther/archive/2008/06/17/asp-net-mvc-tip-3-provide-explicit-view-names-when-unit-testing.aspx</a></p>
<p id="qfzq1" goog_docs_charindex="135">摘要：在这个Tip中，Stephen Walther解释了当控制器action需要返回一个特定的视图时，应该如何进行单元测试。他建议你如果打算建立单元测试的话，还是要明确地指出视图的名称。</p>
<div style="text-align:center">
<script type="text/javascript"><!--
google_ad_client = "pub-0410788977836329";
google_ad_width = 728;
google_ad_height = 90;
google_ad_format = "728x90_as";
google_ad_type = "text_image";
//2007-07-05: cnblogs.com
google_ad_channel = "5389395912";
google_color_border = "336699";
google_color_bg = "FFFFFF";
google_color_link = "0000FF";
google_color_text = "000000";
google_color_url = "008000";
google_ui_features = "rc:0";
//-->
</script>
<script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<p id="h3bw" goog_docs_charindex="234">ASP.NET MVC框架是一个高度可测试的框架。你可以很方便地测试MVC控制器Action，确定它是否能够返回你所期望的结果。在这个Tip中，我会向你展示如何测试一个会返回特定视图的控制器action。</p>
<p id="k1hu" goog_docs_charindex="341">考虑清单1中名为HomeController的MVC控制器。该控制器包含一个名为Index()的action。Index() action返回一个视图。然而，这里并没有提供视图的名字。视图的名字是通过控制器action的名字推断出来的。因此，当你到用Index() action时，会返回名为Index的视图。</p>
<p id="eiil" goog_docs_charindex="501">HomeController还包含另外一个名为Index2()的action。这个action也返回一个视图。然而，这个action明确地指出了视图的名字。视图的名字被传递到View()方法中。该控制器action和第一个控制器action做的事情是相同的。然而，第一个控制器action的视图名字是推断出来的，而第二个控制器action的视图名字是明确指定的。</p>
<p id="f62c" goog_docs_charindex="687">清单1 - HomeController.cs</p>
<div class="cnblogs_code"><span style="color: #008080">&nbsp;1</span><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /><span style="color: #0000ff">using</span><span style="color: #000000">&nbsp;System;<br />
</span><span style="color: #008080">&nbsp;2</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">using</span><span style="color: #000000">&nbsp;System.Collections.Generic;<br />
</span><span style="color: #008080">&nbsp;3</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">using</span><span style="color: #000000">&nbsp;System.Linq;<br />
</span><span style="color: #008080">&nbsp;4</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">using</span><span style="color: #000000">&nbsp;System.Web;<br />
</span><span style="color: #008080">&nbsp;5</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">using</span><span style="color: #000000">&nbsp;System.Web.Mvc;<br />
</span><span style="color: #008080">&nbsp;6</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" />&nbsp;<br />
</span><span style="color: #008080">&nbsp;7</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">namespace</span><span style="color: #000000">&nbsp;Tip3.Controllers<br />
</span><span style="color: #008080">&nbsp;8</span><span style="color: #000000"><img id="Codehighlighter1_136_423_Open_Image" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_136_423_Open_Text').style.display='none'; document.getElementById('Codehighlighter1_136_423_Closed_Image').style.display='inline'; document.getElementById('Codehighlighter1_136_423_Closed_Text').style.display='inline';" alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" /><img style="display: none" id="Codehighlighter1_136_423_Closed_Image" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_136_423_Closed_Text').style.display='none'; document.getElementById('Codehighlighter1_136_423_Open_Image').style.display='inline'; document.getElementById('Codehighlighter1_136_423_Open_Text').style.display='inline';" alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" /></span><span style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid; display: none; background-color: #ffffff" id="Codehighlighter1_136_423_Closed_Text"><img alt="" src="http://www.cnblogs.com/Images/dot.gif" /></span><span id="Codehighlighter1_136_423_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;9</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;HomeController&nbsp;:&nbsp;Controller<br />
</span><span style="color: #008080">10</span><span style="color: #000000"><img id="Codehighlighter1_187_421_Open_Image" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_187_421_Open_Text').style.display='none'; document.getElementById('Codehighlighter1_187_421_Closed_Image').style.display='inline'; document.getElementById('Codehighlighter1_187_421_Closed_Text').style.display='inline';" alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" /><img style="display: none" id="Codehighlighter1_187_421_Closed_Image" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_187_421_Closed_Text').style.display='none'; document.getElementById('Codehighlighter1_187_421_Open_Image').style.display='inline'; document.getElementById('Codehighlighter1_187_421_Open_Text').style.display='inline';" alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid; display: none; background-color: #ffffff" id="Codehighlighter1_187_421_Closed_Text"><img alt="" src="http://www.cnblogs.com/Images/dot.gif" /></span><span id="Codehighlighter1_187_421_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">11</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;ActionResult&nbsp;Index()<br />
</span><span style="color: #008080">12</span><span style="color: #000000"><img id="Codehighlighter1_233_293_Open_Image" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_233_293_Open_Text').style.display='none'; document.getElementById('Codehighlighter1_233_293_Closed_Image').style.display='inline'; document.getElementById('Codehighlighter1_233_293_Closed_Text').style.display='inline';" alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" /><img style="display: none" id="Codehighlighter1_233_293_Closed_Image" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_233_293_Closed_Text').style.display='none'; document.getElementById('Codehighlighter1_233_293_Open_Image').style.display='inline'; document.getElementById('Codehighlighter1_233_293_Open_Text').style.display='inline';" alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid; display: none; background-color: #ffffff" id="Codehighlighter1_233_293_Closed_Text"><img alt="" src="http://www.cnblogs.com/Images/dot.gif" /></span><span id="Codehighlighter1_233_293_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">13</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;View();&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;view&nbsp;name&nbsp;inferred</span><span style="color: #008000"><br />
</span><span style="color: #008080">14</span><span style="color: #008000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">15</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;<br />
</span><span style="color: #008080">16</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;ActionResult&nbsp;Index2()<br />
</span><span style="color: #008080">17</span><span style="color: #000000"><img id="Codehighlighter1_341_408_Open_Image" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_341_408_Open_Text').style.display='none'; document.getElementById('Codehighlighter1_341_408_Closed_Image').style.display='inline'; document.getElementById('Codehighlighter1_341_408_Closed_Text').style.display='inline';" alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" /><img style="display: none" id="Codehighlighter1_341_408_Closed_Image" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_341_408_Closed_Text').style.display='none'; document.getElementById('Codehighlighter1_341_408_Open_Image').style.display='inline'; document.getElementById('Codehighlighter1_341_408_Open_Text').style.display='inline';" alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid; display: none; background-color: #ffffff" id="Codehighlighter1_341_408_Closed_Text"><img alt="" src="http://www.cnblogs.com/Images/dot.gif" /></span><span id="Codehighlighter1_341_408_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">18</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;View(</span><span style="color: #800000">"</span><span style="color: #800000">Index</span><span style="color: #800000">"</span><span style="color: #000000">);&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;view&nbsp;name&nbsp;explicit</span><span style="color: #008000"><br />
</span><span style="color: #008080">19</span><span style="color: #008000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">20</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;<br />
</span><span style="color: #008080">21</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">22</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">23</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span></div>
<p id="f62c" goog_docs_charindex="687">如果你计划为ASP.NET MVC应用程序创建单元测试，则你必需明确指定视图的名字。否则，即便返回了正确的视图，也无法通过单元测试。</p>
<p id="ta8v" goog_docs_charindex="824">清单2的测试类中包含了两个测试方法。第一个方法测试了HomeController的Index() action，第二个方法测试了Index2()。第一个测试总是失败，而第二个测试则能成功（参见图1）。</p>
<p id="t:gl" goog_docs_charindex="929">清单2 - HomeControllerTest.cs</p>
<div class="cnblogs_code"><span style="color: #008080">&nbsp;1</span><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /><span style="color: #0000ff">using</span><span style="color: #000000">&nbsp;System;<br />
</span><span style="color: #008080">&nbsp;2</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">using</span><span style="color: #000000">&nbsp;System.Collections.Generic;<br />
</span><span style="color: #008080">&nbsp;3</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">using</span><span style="color: #000000">&nbsp;System.Linq;<br />
</span><span style="color: #008080">&nbsp;4</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">using</span><span style="color: #000000">&nbsp;System.Text;<br />
</span><span style="color: #008080">&nbsp;5</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">using</span><span style="color: #000000">&nbsp;System.Web.Mvc;<br />
</span><span style="color: #008080">&nbsp;6</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">using</span><span style="color: #000000">&nbsp;Microsoft.VisualStudio.TestTools.UnitTesting;<br />
</span><span style="color: #008080">&nbsp;7</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">using</span><span style="color: #000000">&nbsp;Tip3;<br />
</span><span style="color: #008080">&nbsp;8</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">using</span><span style="color: #000000">&nbsp;Tip3.Controllers;<br />
</span><span style="color: #008080">&nbsp;9</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" />&nbsp;<br />
</span><span style="color: #008080">10</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">namespace</span><span style="color: #000000">&nbsp;Tip3Tests.Controllers<br />
</span><span style="color: #008080">11</span><span style="color: #000000"><img id="Codehighlighter1_230_1035_Open_Image" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_230_1035_Open_Text').style.display='none'; document.getElementById('Codehighlighter1_230_1035_Closed_Image').style.display='inline'; document.getElementById('Codehighlighter1_230_1035_Closed_Text').style.display='inline';" alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" /><img style="display: none" id="Codehighlighter1_230_1035_Closed_Image" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_230_1035_Closed_Text').style.display='none'; document.getElementById('Codehighlighter1_230_1035_Open_Image').style.display='inline'; document.getElementById('Codehighlighter1_230_1035_Open_Text').style.display='inline';" alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" /></span><span style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid; display: none; background-color: #ffffff" id="Codehighlighter1_230_1035_Closed_Text"><img alt="" src="http://www.cnblogs.com/Images/dot.gif" /></span><span id="Codehighlighter1_230_1035_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">12</span><span style="color: #000000"><img id="Codehighlighter1_236_320_Open_Image" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_236_320_Open_Text').style.display='none'; document.getElementById('Codehighlighter1_236_320_Closed_Image').style.display='inline'; document.getElementById('Codehighlighter1_236_320_Closed_Text').style.display='inline';" alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" /><img style="display: none" id="Codehighlighter1_236_320_Closed_Image" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_236_320_Closed_Text').style.display='none'; document.getElementById('Codehighlighter1_236_320_Open_Image').style.display='inline'; document.getElementById('Codehighlighter1_236_320_Open_Text').style.display='inline';" alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid; display: none; background-color: #ffffff" id="Codehighlighter1_236_320_Closed_Text">/**/</span><span id="Codehighlighter1_236_320_Open_Text"><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br />
</span><span style="color: #008080">13</span><span style="color: #008000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;Summary&nbsp;description&nbsp;for&nbsp;HomeControllerTest<br />
</span><span style="color: #008080">14</span><span style="color: #008000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span></span><br />
<span style="color: #008080">15</span><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;[TestClass]<br />
</span><span style="color: #008080">16</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;HomeControllerTest<br />
</span><span style="color: #008080">17</span><span style="color: #000000"><img id="Codehighlighter1_376_1033_Open_Image" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_376_1033_Open_Text').style.display='none'; document.getElementById('Codehighlighter1_376_1033_Closed_Image').style.display='inline'; document.getElementById('Codehighlighter1_376_1033_Closed_Text').style.display='inline';" alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" /><img style="display: none" id="Codehighlighter1_376_1033_Closed_Image" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_376_1033_Closed_Text').style.display='none'; document.getElementById('Codehighlighter1_376_1033_Open_Image').style.display='inline'; document.getElementById('Codehighlighter1_376_1033_Open_Text').style.display='inline';" alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid; display: none; background-color: #ffffff" id="Codehighlighter1_376_1033_Closed_Text"><img alt="" src="http://www.cnblogs.com/Images/dot.gif" /></span><span id="Codehighlighter1_376_1033_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">18</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[TestMethod]<br />
</span><span style="color: #008080">19</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;Index()<br />
</span><span style="color: #008080">20</span><span style="color: #000000"><img id="Codehighlighter1_435_697_Open_Image" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_435_697_Open_Text').style.display='none'; document.getElementById('Codehighlighter1_435_697_Closed_Image').style.display='inline'; document.getElementById('Codehighlighter1_435_697_Closed_Text').style.display='inline';" alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" /><img style="display: none" id="Codehighlighter1_435_697_Closed_Image" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_435_697_Closed_Text').style.display='none'; document.getElementById('Codehighlighter1_435_697_Open_Image').style.display='inline'; document.getElementById('Codehighlighter1_435_697_Open_Text').style.display='inline';" alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid; display: none; background-color: #ffffff" id="Codehighlighter1_435_697_Closed_Text"><img alt="" src="http://www.cnblogs.com/Images/dot.gif" /></span><span id="Codehighlighter1_435_697_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">21</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;Arrange</span><span style="color: #008000"><br />
</span><span style="color: #008080">22</span><span style="color: #008000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HomeController&nbsp;controller&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;HomeController();<br />
</span><span style="color: #008080">23</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;<br />
</span><span style="color: #008080">24</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;Act</span><span style="color: #008000"><br />
</span><span style="color: #008080">25</span><span style="color: #008000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ViewResult&nbsp;result&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;controller.Index()&nbsp;</span><span style="color: #0000ff">as</span><span style="color: #000000">&nbsp;ViewResult;<br />
</span><span style="color: #008080">26</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;<br />
</span><span style="color: #008080">27</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;Assert</span><span style="color: #008000"><br />
</span><span style="color: #008080">28</span><span style="color: #008000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.AreEqual(</span><span style="color: #800000">"</span><span style="color: #800000">Index</span><span style="color: #800000">"</span><span style="color: #000000">,&nbsp;result.ViewName);<br />
</span><span style="color: #008080">29</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">30</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;<br />
</span><span style="color: #008080">31</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;<br />
</span><span style="color: #008080">32</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[TestMethod]<br />
</span><span style="color: #008080">33</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;Index2()<br />
</span><span style="color: #008080">34</span><span style="color: #000000"><img id="Codehighlighter1_760_1023_Open_Image" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_760_1023_Open_Text').style.display='none'; document.getElementById('Codehighlighter1_760_1023_Closed_Image').style.display='inline'; document.getElementById('Codehighlighter1_760_1023_Closed_Text').style.display='inline';" alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" /><img style="display: none" id="Codehighlighter1_760_1023_Closed_Image" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_760_1023_Closed_Text').style.display='none'; document.getElementById('Codehighlighter1_760_1023_Open_Image').style.display='inline'; document.getElementById('Codehighlighter1_760_1023_Open_Text').style.display='inline';" alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid; display: none; background-color: #ffffff" id="Codehighlighter1_760_1023_Closed_Text"><img alt="" src="http://www.cnblogs.com/Images/dot.gif" /></span><span id="Codehighlighter1_760_1023_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">35</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;Arrange</span><span style="color: #008000"><br />
</span><span style="color: #008080">36</span><span style="color: #008000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HomeController&nbsp;controller&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;HomeController();<br />
</span><span style="color: #008080">37</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;<br />
</span><span style="color: #008080">38</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;Act</span><span style="color: #008000"><br />
</span><span style="color: #008080">39</span><span style="color: #008000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ViewResult&nbsp;result&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;controller.Index2()&nbsp;</span><span style="color: #0000ff">as</span><span style="color: #000000">&nbsp;ViewResult;<br />
</span><span style="color: #008080">40</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;<br />
</span><span style="color: #008080">41</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;Assert</span><span style="color: #008000"><br />
</span><span style="color: #008080">42</span><span style="color: #008000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.AreEqual(</span><span style="color: #800000">"</span><span style="color: #800000">Index</span><span style="color: #800000">"</span><span style="color: #000000">,&nbsp;result.ViewName);<br />
</span><span style="color: #008080">43</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">44</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;<br />
</span><span style="color: #008080">45</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" />&nbsp;<br />
</span><span style="color: #008080">46</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">47</span><span style="color: #000000"><img alt="" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" />}</span></span></div>
<p id="t:gl" goog_docs_charindex="929">图1 - 单元测试结果<br />
<img border="0" alt="" src="http://weblogs.asp.net/blogs/stephenwalther/WindowsLiveWriter/ASP.NETMVCTip3ProvideExplicitViewNameswh_87BE/image_thumb.png" /></p>
<p id="x1pz3" goog_docs_charindex="1019">单元测试无法推断视图名字。我的建议是，如果打算进行单元测试，应该总是明确指定视图的名字。<br />
<br />
此处下载源代码：<font face="Verdana"><a href="http://weblogs.asp.net/blogs/stephenwalther/Downloads/Tip3/Tip3.zip">http://weblogs.asp.net/blogs/stephenwalther/Downloads/Tip3/Tip3.zip</a>。<br />
<br />
------<br />
<br />
广告：欢迎光临[.NET正则表达式库] <a href="http://regex-lib.net/">http://regex-lib.net/</a>。</font></p> <img src ="http://www.cnblogs.com/AndersLiu/aggbug/1236813.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41300/" target="_blank">[新闻]十几万元天价笔记本电脑</a>]]></description></item></channel></rss>