调试 ASP.NET 网页 (Razor) 站点简介

作者 Tom FitzMacken

本文介绍调试 ASP.NET 网页 (Razor) 网站中的页面的各种方法。 调试是在代码页中查找和修复错误的过程。

你将了解的内容:

  • 如何显示有助于分析和调试页面的信息。
  • 如何在 Visual Studio 中使用调试工具。

以下是本文中介绍的 ASP.NET 功能:

  • 帮助 ServerInfo 程序。
  • ObjectInfo 帮手。

软件版本

  • ASP.NET 网页 (Razor) 3
  • Visual Studio 2013

本教程也适用于 ASP.NET 网页 2。 可以使用 WebMatrix 3,但不支持集成调试器。

排查代码中的错误和问题的一个重要方面是首先避免它们。 可以通过将可能导致错误的代码部分放入块中 try/catch 来执行此操作。 有关详细信息,请参阅 使用 Razor 语法 ASP.NET Web 编程简介中有关处理错误的部分。

帮助 ServerInfo 程序是一种诊断工具,可让你大致了解托管页面的 Web 服务器环境的信息。 它还显示浏览器请求页面时发送的 HTTP 请求信息。 帮助 ServerInfo 程序显示当前用户标识、发出请求的浏览器类型等。 此类信息可以帮助你排查常见问题。

  1. 创建名为 ServerInfo.cshtml 的新网页。

  2. 在页面末尾的结束 </body> 标记之前,添加 @ServerInfo.GetHtml()

    <!DOCTYPE html>
    <html>
        <head>
            <title></title>
        </head>
        <body>
       @ServerInfo.GetHtml()
        </body>
    </html>
    

    可以在页面的 ServerInfo 任意位置添加代码。 但将其添加到末尾会使其输出与其他页面内容分开,从而使其更易于阅读。

    注意

    重要 在将网页移动到生产服务器之前,应从网页中删除任何诊断代码。 这适用于 ServerInfo 帮助程序以及本文中涉及将代码添加到页面的其他诊断技术。 您不希望网站访问者看到有关您的服务器名称、用户名、服务器上的路径以及类似详细信息的信息,因为这种类型的信息可能对具有恶意意图的用户有用。

  3. 保存页面并在浏览器中运行它。

    Debugging-1

    帮助 ServerInfo 程序在页面中显示四个信息表:

    • 服务器配置。 本部分提供有关托管 Web 服务器的信息,包括计算机名称、正在运行 ASP.NET 的版本、域名和服务器时间。

    • ASP.NET 服务器变量。 本部分提供有关许多 HTTP 协议详细信息的详细信息, (称为 HTTP 变量) 以及每个网页请求的一部分的值。

    • HTTP 运行时信息。 本部分提供了有关运行网页的 Microsoft .NET Framework版本、路径、缓存详细信息等的详细信息。 (如使用 Razor 语法 ASP.NET Web 编程简介中所述,使用 Razor 语法 ASP.NET 网页基于 Microsoft ASP.NET Web 服务器技术构建,该技术本身基于名为 .NET Framework.)

    • 环境变量。 本部分提供 Web 服务器上所有本地环境变量及其值的列表。

      所有服务器和请求信息的完整说明超出了本文的范围,但可以看到 ServerInfo 帮助程序返回了大量诊断信息。 有关返回的值 ServerInfo 的详细信息,请参阅 Microsoft TechNet 网站上的 已识别环境变量 和 MSDN 网站上的 IIS 服务器变量

嵌入输出表达式以显示页面值

查看代码中发生的情况的另一种方法是在页面中嵌入输出表达式。 如你所知,可以通过向页面添加类似于 @myVariable@(subTotal * 12) 的内容来直接输出变量的值。 对于调试,可以将这些输出表达式放置在代码中的战略点。 这使你可以在页面运行时查看键变量的值或计算结果。 完成调试后,可以删除表达式或将其注释掉。此过程说明了使用嵌入表达式帮助调试页面的典型方法。

  1. 创建名为 OutputExpression.cshtml 的新 WebMatrix 页。

  2. 将页面内容替换为以下内容:

    <!DOCTYPE html>
    <html>
        <head>
            <title></title>
        </head>
        <body>   
    
        @{
            var weekday = DateTime.Now.DayOfWeek;
            // As a test, add 1 day to the current weekday.
            if(weekday.ToString() != "Saturday") {
                // If weekday is not Saturday, simply add one day.
                weekday = weekday + 1; 
            }
            else {
                // If weekday is Saturday, reset the day to 0, or Sunday.
                weekday = 0; 
            }
            // Convert weekday to a string value for the switch statement.
            var weekdayText = weekday.ToString(); 
    
            var greeting = "";
            
            switch(weekdayText) 
            { 
                case "Monday":
                    greeting = "Ok, it's a marvelous Monday."; 
                    break; 
                case "Tuesday":
                    greeting = "It's a tremendous Tuesday.";
                    break; 
                case "Wednesday":
                    greeting = "Wild Wednesday is here!";
                    break; 
                case "Thursday":
                    greeting = "All right, it's thrifty Thursday.";
                    break;
                case "Friday":
                    greeting = "It's finally Friday!";
                    break;
                case "Saturday":
                    greeting = "Another slow Saturday is here.";
                    break;
                case "Sunday":
                    greeting = "The best day of all: serene Sunday.";
                    break;
                default:
                    break; 
            }
        }
        
        <h2>@greeting</h2>
    
        </body>
    </html>
    

    该示例使用 语句switch检查变量的值,weekday然后根据星期几显示不同的输出消息。 在此示例中, if 第一个代码块中的 块通过将一天添加到当前工作日值来任意更改星期几。 这是为了说明而引入的错误。

  3. 保存页面并在浏览器中运行它。

    页面显示一周中错误的某一天的消息。 无论它实际在一周中的哪一天,你都会在一天后看到该消息。 虽然在这种情况下,你知道消息关闭的原因 (因为代码故意设置不正确的日期值) ,但实际上通常很难知道代码中哪里出了问题。 若要进行调试,需要了解关键对象和变量(如 weekday)的值发生的情况。

  4. 通过插入 来添加输出表达式, @weekday 如代码中的注释所指示的两个位置所示。 这些输出表达式将在代码执行时显示变量的值。

    var weekday = DateTime.Now.DayOfWeek;
    // DEBUG: Display the initial value of weekday. 
    @weekday
    
    // As a test, add 1 day to the current weekday.
    if(weekday.ToString() != "Saturday") {
        // If weekday is not Saturday, simply add one day.
        weekday = weekday + 1; 
    }
    else {
        // If weekday is Saturday, reset the day to 0, or Sunday.
        weekday = 0; 
    }
    
    // DEBUG: Display the updated test value of weekday.
    @weekday
    
    // Convert weekday to a string value for the switch statement.
    var weekdayText = weekday.ToString();
    
  5. 在浏览器中保存并运行页面。

    该页首先显示一周中的实际日期,然后显示添加一天所导致的一周中的更新日期,然后显示语句中 switch 生成的消息。 两个变量表达式的输出 (@weekday) 之间没有空格,因为你没有向输出添加任何 HTML <p> 标记;表达式仅用于测试。

    Debugging-2

    现在可以看到错误的位置。 首次在代码中显示 weekday 变量时,它将显示正确的日期。 当你第二次显示它时,在代码中的 块之后 if ,一天将休息一次。 因此,你知道在工作日变量的第一次和第二次出现之间发生了一些事情。 如果这是一个真正的 bug,这种方法将帮助你缩小导致问题的代码的位置。

  6. 通过删除添加的两个输出表达式并删除更改星期日期的代码,修复页面中的代码。 剩余的完整代码块如以下示例所示:

    @{
        var weekday = DateTime.Now.DayOfWeek;
        var weekdayText = weekday.ToString(); 
    
        var greeting = "";
            
        switch(weekdayText) 
        { 
            case "Monday":
                greeting = "Ok, it's a marvelous Monday."; 
                break; 
            case "Tuesday":
                greeting = "It's a tremendous Tuesday.";
                break; 
            case "Wednesday":
                greeting = "Wild Wednesday is here!";
                break; 
            case "Thursday":
                greeting = "All right, it's thrifty Thursday.";
                break;
            case "Friday":
                greeting = "It's finally Friday!";
                break;
            case "Saturday":
                greeting = "Another slow Saturday is here.";
                break;
            case "Sunday":
                greeting = "The best day of all: serene Sunday.";
                break;
            default:
                break; 
        }
    }
    
  7. 在浏览器中运行页面。 这一次,你会看到针对一周中实际日期显示的正确消息。

使用 ObjectInfo 帮助程序显示对象值

帮助 ObjectInfo 程序显示传递给它的每个对象的类型和值。 可以使用它来查看代码中变量和对象的值, (如上一示例) 中对输出表达式所做的那样,还可以查看有关对象的数据类型信息。

  1. 打开前面创建的名为 OutputExpression.cshtml 的文件。

  2. 将页面中的所有代码替换为以下代码块:

    <!DOCTYPE html>
    <html>
        <head>
            <title></title>
        </head>
        <body>
        @{
          var weekday = DateTime.Now.DayOfWeek;
          @ObjectInfo.Print(weekday)
          var weekdayText = weekday.ToString(); 
      
          var greeting = "";
      
          switch(weekdayText) 
          { 
              case "Monday":
                  greeting = "Ok, it's a marvelous Monday."; 
                  break; 
              case "Tuesday":
                  greeting = "It's a tremendous Tuesday.";
                  break; 
              case "Wednesday":
                  greeting = "Wild Wednesday is here!";
                  break; 
              case "Thursday":
                  greeting = "All right, it's thrifty Thursday.";
                  break;
              case "Friday":
                  greeting = "It's finally Friday!";
                  break;
               case "Saturday":
                  greeting = "Another slow Saturday is here.";
                  break;
               case "Sunday":
                  greeting = "The best day of all: serene Sunday.";
                  break;
              default:
                  break; 
          }
        }
        @ObjectInfo.Print(greeting)
        <h2>@greeting</h2>
    
        </body>
    </html>
    
  3. 在浏览器中保存并运行页面。

    Debugging-4

    在此示例中, ObjectInfo 帮助程序显示两项:

    • 类型。 对于第一个变量,类型为 DayOfWeek。 对于第二个变量,类型为 String

    • 值。 在这种情况下,由于已在页面中显示 greeting 变量的值,因此将变量传递给 ObjectInfo时会再次显示该值。

      对于更复杂的对象, ObjectInfo 帮助程序可以显示更多信息, 基本上,它可以显示对象的所有属性的类型和值。

在 Visual Studio 中使用调试工具

若要获得更全面的调试体验,请使用 Visual Studio。 使用 Visual Studio,可以在代码中设置要检查的行的断点。

设置断点

测试网站时,执行的代码会在断点处停止。

到达断点

可以检查变量的当前值,并逐行执行代码。

查看值

有关在 Visual Studio 中使用集成调试器调试 ASP.NET Razor 页面的信息,请参阅使用 Visual Studio ASP.NET 网页 (Razor) 编程

其他资源