使用 Razor 语法进行 ASP.NET Web 编程 (C#) 简介

作者: Tom FitzMacken

本文概述了如何使用 Razor 语法通过 ASP.NET 网页进行编程。 ASP.NET 是Microsoft在 Web 服务器上运行动态网页的技术。 本文重点介绍如何使用 C# 编程语言。

你将了解的内容:

  • 使用 Razor 语法对编程 ASP.NET 网页入门的前 8 个编程提示。
  • 需要的基本编程概念。
  • ASP.NET 服务器代码和 Razor 语法的全部内容。

软件版本

  • ASP.NET 网页 (Razor) 3

本教程也适用于 ASP.NET 网页 2。

前 8 个编程提示

本部分列出了一些提示,当你开始使用 Razor 语法编写 ASP.NET 服务器代码时,你绝对需要知道这些提示。

注意

Razor 语法基于 C# 编程语言,这是最常用于 ASP.NET 网页的语言。 但是,Razor 语法还支持 Visual Basic 语言,并且你所看到的一切也可以在 Visual Basic 中执行。 有关详细信息,请参阅附录 Visual Basic 语言和语法

可以在本文后面找到有关其中大多数编程技术的更多详细信息。

1.使用 @ 字符向页面添加代码

字符 @ 启动内联表达式、单语句块和多语句块:

<!-- Single statement blocks  -->
@{ var total = 7; }
@{ var myMessage = "Hello World"; }

<!-- Inline expressions -->
<p>The value of your account is: @total </p>
<p>The value of myMessage is: @myMessage</p>

<!-- Multi-statement block -->
@{
    var greeting = "Welcome to our site!";
    var weekDay = DateTime.Now.DayOfWeek;
    var greetingMessage = greeting + " Today is: " + weekDay;
}
<p>The greeting is: @greetingMessage</p>

在浏览器中运行页面时,这些语句如下所示:

Razor-Img1

提示

HTML 编码

使用 @ 字符在页面中显示内容时,如前面的示例所示,ASP.NET HTML 编码输出。 这会将保留的 HTML 字符(如 <>&替换为允许在网页中显示为字符的代码,而不是解释为 HTML 标记或实体。 如果没有 HTML 编码,服务器代码的输出可能无法正确显示,并且可能会向安全风险公开页面。

如果你的目标是输出将标记呈现为标记的 HTML 标记(例如<p></p>段落或<em></em>强调文本),请参阅本文稍后在代码块中组合文本、标记和代码部分

可以在“使用表单”中详细了解 HTML 编码。

2. 将代码块括在大括号中

代码 包括一个或多个代码语句,并括在大括号中。

<!-- Single statement block.  -->
@{ var theMonth = DateTime.Now.Month; }
<p>The numeric value of the current month: @theMonth</p>

<!-- Multi-statement block. -->
@{
    var outsideTemp = 79;
    var weatherMessage = "Hello, it is " + outsideTemp + " degrees.";
}
<p>Today's weather: @weatherMessage</p>

结果显示在浏览器中:

Razor-Img2

3. 在块内,使用分号结束每个代码语句

在代码块内,每个完整的代码语句必须以分号结尾。 内联表达式不以分号结尾。

<!-- Single-statement block -->
@{ var theMonth = DateTime.Now.Month; }

<!-- Multi-statement block -->
@{
    var outsideTemp = 79;
    var weatherMessage = "Hello, it is " + outsideTemp + " degrees.";
}

<!-- Inline expression, so no semicolon -->
<p>Today's weather: @weatherMessage</p>

4. 使用变量来存储值

可以将值存储在变量,包括字符串、数字和日期等。使用var关键字创建新变量。 可以使用 在页面中 @直接插入变量值。

<!-- Storing a string -->
@{ var welcomeMessage = "Welcome, new members!"; }
<p>@welcomeMessage</p>

<!-- Storing a date -->
@{ var year = DateTime.Now.Year; }

<!-- Displaying a variable -->
<p>Welcome to our new members who joined in @year!</p>

结果显示在浏览器中:

Razor-Img3

5. 用双引号将文本字符串值括起来

字符串是被视为文本的字符序列。 若要指定字符串,请用双引号将其括起来:

@{ var myString = "This is a string literal"; }

如果要显示的字符串包含反斜杠字符( \ )或双引号( " ),请使用带有运算符前缀@的逐字字符串文本。 (在 C# 中,除非使用逐字字符串文本,否则 \ 字符具有特殊含义。

<!-- Embedding a backslash in a string -->
@{ var myFilePath = @"C:\MyFolder\"; }
<p>The path is: @myFilePath</p>

若要嵌入双引号,请使用逐字字符串文本并重复引号:

<!-- Embedding double quotation marks in a string -->
@{ var myQuote = @"The person said: ""Hello, today is Monday."""; }
<p>@myQuote</p>

下面是在页面中使用这两个示例的结果:

Razor-Img4

注意

请注意,该 @ 字符既用于标记 C# 中的逐字字符串文本,也用于标记 ASP.NET 页面中的代码。

6.代码区分大小写

在 C# 中,关键字(如 vartrueif和变量名称区分大小写。 以下代码行创建两个不同的变量, lastName 以及 LastName.

@{
    var lastName = "Smith";
    var LastName = "Jones";
}

如果将变量声明为 var lastName = "Smith"; 变量并尝试引用页面中 @LastName的变量,则获取值 "Jones" 而不是 "Smith"

注意

在 Visual Basic 中,关键字和变量 区分大小写。

7. 大部分编码都涉及对象

对象表示可以编程的内容:页面、文本框、文件、图像、Web 请求、电子邮件、客户记录(数据库行)等。对象具有描述其特征的属性,并且可以读取或更改 — 文本框对象具有Text属性(等等),请求对象具有Url属性, 电子邮件具有属性From,客户对象具有属性FirstName。 对象还具有其可执行的“谓词”方法。 示例包括文件对象 Save 的方法、图像对象的 Rotate 方法和电子邮件对象 Send 的方法。

你经常使用对象 Request ,该对象提供诸如页面上文本框(窗体字段)的值、浏览器发出的请求类型、页面的 URL、用户标识等信息。以下示例演示如何访问对象的属性 Request 以及如何调用 MapPath 对象的方法 Request ,从而提供服务器上的页面的绝对路径:

<table border="1">
<tr>
    <td>Requested URL</td>
    <td>Relative Path</td>
    <td>Full Path</td>
    <td>HTTP Request Type</td>
</tr>
<tr>
    <td>@Request.Url</td>
    <td>@Request.FilePath</td>
    <td>@Request.MapPath(Request.FilePath)</td>
    <td>@Request.RequestType</td>
</tr>
</table>

结果显示在浏览器中:

Razor-Img5

8. 可以编写做出决策的代码

动态网页的主要功能是,你可以根据条件确定要执行的操作。 执行此操作的最常见方法是使用 if 语句(和可选 else 语句)。

@{
   var result = "";
   if(IsPost)
   {
      result = "This page was posted using the Submit button.";
   }
   else
   {
      result = "This was the first request for this page.";
   }
}

<!DOCTYPE html>
<html>
    <head>
        <title></title>
    </head>
<body>
<form method="POST" action="" >
  <input type="Submit" name="Submit" value="Submit"/>
  <p>@result</p>
</form>
</body>
</html>

该语句 if(IsPost) 是一种简写方式 if(IsPost == true)。 除了 if 语句,还有各种方法来测试条件、重复代码块等,本文稍后将对此进行介绍。

结果显示在浏览器中(单击“提交后):

Razor-Img6

提示

HTTP GET 和 POST 方法和 IsPost 属性

用于网页(HTTP)的协议支持用于向服务器发出请求的方法(谓词)数量非常有限。 最常见的两个是 GET,用于读取页面,POST 用于提交页面。 通常,用户第一次请求页面时,将使用 GET 请求页面。 如果用户填写表单,然后单击提交按钮,浏览器会向服务器发出 POST 请求。

在 Web 编程中,了解页面是作为 GET 请求还是 POST,以便知道如何处理页面,这通常很有用。 在 ASP.NET 网页中,可以使用IsPost该属性来查看请求是 GET 还是 POST。 如果请求是 POST,则 IsPost 属性将返回 true,你可以执行诸如读取窗体上文本框的值之类的操作。 你将看到许多示例演示如何根据页面的值 IsPost以不同的方式处理页面。

简单代码示例

此过程演示如何创建说明基本编程技术的页面。 在本示例中,你将创建一个页面,允许用户输入两个数字,然后添加它们并显示结果。

  1. 在编辑器中,创建新的文件并将其命名为 AddNumbers.cshtml

  2. 将以下代码和标记复制到页面中,替换页面中已有的任何内容。

    @{
        var total = 0;
        var totalMessage = "";
        if(IsPost) {
    
            // Retrieve the numbers that the user entered.
            var num1 = Request["text1"];
            var num2 = Request["text2"];
    
            // Convert the entered strings into integers numbers and add.
            total = num1.AsInt() + num2.AsInt();
            totalMessage = "Total = " + total;
        }
    }
    
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <title>Add Numbers</title>
        <meta charset="utf-8" />
        <style type="text/css">
          body {background-color: beige; font-family: Verdana, Arial;
                margin: 50px; }
          form {padding: 10px; border-style: solid; width: 250px;}
        </style>
      </head>
    <body>
      <p>Enter two whole numbers and then click <strong>Add</strong>.</p>
      <form action="" method="post">
        <p><label for="text1">First Number:</label>
          <input type="text" name="text1" />
        </p>
        <p><label for="text2">Second Number:</label>
          <input type="text" name="text2" />
        </p>
        <p><input type="submit" value="Add" /></p>
      </form>
    
      <p>@totalMessage</p>
    
    </body>
    </html>
    

    以下是需要注意的一些事项:

    • @ 字符启动页面中的第一个代码块,该代码块位于页面底部附近的变量前面 totalMessage
    • 页面顶部的块用大括号括起来。
    • 在顶部的块中,所有行以分号结尾。
    • 变量 totalnum1变量 num2totalMessage 存储多个数字和字符串。
    • 分配给 totalMessage 变量的文本字符串值采用双引号。
    • 由于代码区分大小写,因此当 totalMessage 变量在页面底部附近使用时,其名称必须与顶部的变量完全匹配。
    • num1.AsInt() + num2.AsInt()表达式演示如何使用对象和方法。 AsInt每个变量上的方法将用户输入的字符串转换为数字(整数),以便可以对它执行算术。
    • 标记 <form> 包括一个 method="post" 属性。 这指定当用户单击“添加时,将使用 HTTP POST 方法将页面发送到服务器。 提交页面后,测试 if(IsPost) 的计算结果为 true,条件代码运行,显示添加数字的结果。
  3. 保存页面并在浏览器中运行。 (请确保在 中选择 了页面运行前的文件 工作区。输入两个整数,然后单击“ 添加 ”按钮。

    Razor-Img7

基本编程概念

本文概述了 ASP.NET Web 编程。 这不是详尽的检查,只是一个快速浏览你最常使用的编程概念。 即便如此,它几乎涵盖了开始使用 ASP.NET 网页所需的一切。

但首先,有点技术背景。

Razor 语法、服务器代码和 ASP.NET

Razor 语法是一个简单的编程语法,用于在网页中嵌入基于服务器的代码。 在使用 Razor 语法的网页中,有两种内容:客户端内容和服务器代码。 客户端内容是您在网页中使用的内容:HTML 标记(元素)、样式信息(如 CSS)、某些客户端脚本(如 JavaScript)和纯文本。

使用 Razor 语法可将服务器代码添加到此客户端内容。 如果页面中包含服务器代码,则服务器会先运行该代码,然后再将页面发送到浏览器。 通过在服务器上运行,代码可以执行更复杂的任务,单独使用客户端内容(例如访问基于服务器的数据库)。 最重要的是,服务器代码可以动态创建客户端内容 - 它可以动态生成 HTML 标记或其他内容,然后将其发送到浏览器以及页面可能包含的任何静态 HTML。 从浏览器的角度来看,服务器代码生成的客户端内容与任何其他客户端内容没有什么不同。 如你所见,所需的服务器代码非常简单。

ASP.NET 包含 Razor 语法的网页具有特殊的文件扩展名(.cshtml 或 .vbhtml)。 服务器识别这些扩展,运行使用 Razor 语法标记的代码,然后将页面发送到浏览器。

ASP.NET 适合在哪里?

Razor 语法基于Microsoft称为 ASP.NET 的技术,而Microsoft .NET Framework。 The.NET Framework 是一个大型的、全面的编程框架,Microsoft用于开发任何类型的计算机应用程序。 ASP.NET 是专用于创建 Web 应用程序的 .NET Framework 的一部分。 开发人员已使用 ASP.NET 来创建世界上许多最大和最高的网站。 (每当在网站中看到文件扩展名 .aspx 作为 URL 的一部分时,都会知道网站是使用 ASP.NET 编写的。

Razor 语法为你提供了 ASP.NET 的所有功能,但是如果你是初学者,则使用简化的语法可以更轻松地学习,如果你是专家,则可以提高工作效率。 尽管这种语法易于使用,但其与 ASP.NET 和 .NET Framework 的家庭关系意味着,随着网站变得越来越复杂,你拥有可供使用的更大框架的强大功能。

Razor-Img8

提示

类和实例

ASP.NET 服务器代码使用对象,这些对象又基于类的想法而生成。 类是对象的定义或模板。 例如,应用程序可能包含定义 Customer 任何客户对象所需的属性和方法的类。

当应用程序需要使用实际客户信息时,它会创建客户对象的实例(或 实例化)。 每个客户都是类的 Customer 单独实例。 每个实例都支持相同的属性和方法,但每个实例的属性值通常不同,因为每个客户对象都是唯一的。 在一个客户对象中,该 LastName 属性可能是“Smith”;在另一个客户对象中,该 LastName 属性可能是“Jones”。

同样,网站中的任何单个网页都是 Page 类实例的对象 Page 。 页面上的按钮是类 Button 的实例 Button 的对象,依此类说。 每个实例都有自己的特征,但它们都基于对象类定义中指定的内容。

基本语法

前面介绍了如何创建 ASP.NET 网页页的基本示例,以及如何将服务器代码添加到 HTML 标记。 在这里,你将了解使用 Razor 语法(即编程语言规则)编写 ASP.NET 服务器代码的基础知识。

如果你对编程有经验(特别是如果你使用了 C、C++、C#、Visual Basic 或 JavaScript),那么此处阅读的大部分内容都会很熟悉。 你可能需要仅熟悉将服务器代码添加到 .cshtml 文件中的标记的方式

组合代码块中的文本、标记和代码

在服务器代码块中,通常需要将文本或标记(或两者)输出到页面。 如果服务器代码块包含的文本不是代码,而是应按原样呈现,ASP.NET 需要能够区分该文本与代码。 有多种方法可实现此目的。

  • 将文本括在 HTML 元素中,例如 <p></p><em></em>

    @if(IsPost) {
        // This line has all content between matched <p> tags.
        <p>Hello, the time is @DateTime.Now and this page is a postback!</p>
    } else {
        // All content between matched tags, followed by server code.
        <p>Hello <em>stranger</em>, today is: <br /> </p>  @DateTime.Now
    }
    

    HTML 元素可以包括文本、其他 HTML 元素和服务器代码表达式。 当 ASP.NET 看到打开的 HTML 标记(例如, <p>),它将呈现所有内容(包括元素及其内容)与浏览器一样,并解析服务器代码表达式。

  • 使用 @: 运算符或 <text> 元素。 输出 @: 包含纯文本或不匹配 HTML 标记的单个内容行;该 <text> 元素包含多行要输出。 当不想将 HTML 元素呈现为输出的一部分时,这些选项非常有用。

    @if(IsPost) {
        // Plain text followed by an unmatched HTML tag and server code.
        @: The time is: <br /> @DateTime.Now
        <br/>
        // Server code and then plain text, matched tags, and more text.
        @DateTime.Now @:is the <em>current</em> time.
    }
    

    如果要输出多行文本或不匹配的 HTML 标记,可以在每行前面加上 @:,也可以将行括在元素 <text> 中。 @:与运算符一样,<text>标记由 ASP.NET 用于标识文本内容,并且永远不会在页面输出中呈现。

    @if(IsPost) {
        // Repeat the previous example, but use <text> tags.
        <text>
        The time is: <br /> @DateTime.Now
        <br/>
        @DateTime.Now is the <em>current</em> time.
        </text>
    }
    
    @{
        var minTemp = 75;
        <text>It is the month of @DateTime.Now.ToString("MMMM"), and
        it's a <em>great</em> day! <br /><p>You can go swimming if it's at
        least @minTemp degrees. </p></text>
    }
    

    第一个示例重复上一个示例,但使用一对 <text> 标记将文本括起来呈现。 第二个示例中, <text></text> 标记包含三行,所有这些行都有一些未连接的文本和不匹配的 HTML 标记(<br />),以及服务器代码和匹配的 HTML 标记。 同样,还可以分别在每行前面加上 @: 运算符;无论哪种方式都有效。

    注意

    输出文本时,如本部分所示(使用 HTML 元素、 @: 运算符或 <text> 元素),ASP.NET 不会对输出进行 HTML 编码。 (如前所述,ASP.NET 对前面 @所述的服务器代码表达式和服务器代码块的输出进行编码,但本部分所述的特殊情况除外。

空格

语句中的额外空格(和字符串文本外部)不会影响语句:

@{ var lastName =    "Smith"; }

语句中的换行符对语句没有影响,你可以包装语句以便可读性。 以下语句相同:

@{ var theName =
"Smith"; }

@{
    var
    personName
    =
    "Smith"
    ;
}

但是,不能在字符串文本中间换行。 以下示例无法工作:

@{ var test = "This is a long
    string"; }  // Does not work!

若要组合一个长字符串,它包装到多个行,如上面的代码,有两个选项。 可以使用串联运算符 (+),本文稍后将看到该运算符。 还可以使用 @ 字符创建逐字字符串文本,如本文前面所述。 可以跨行中断逐字字符串文本:

@{ var longString = @"This is a
    long
    string";
}

代码(和标记)注释

批注可让你为自己或其他人留下笔记。 它们还允许你禁用(注释掉)不想运行但希望暂时保留在页面中的代码或标记部分。

Razor 代码和 HTML 标记有不同的注释语法。 与所有 Razor 代码一样,在将页面发送到浏览器之前,会在服务器上处理 Razor 注释(然后删除)。 因此,使用 Razor 注释语法可以将注释放入代码(甚至标记),你可以在编辑文件时看到,但用户甚至看不到页面源。

对于 ASP.NET Razor 注释,请使用它开头 @* 并用它结束注释 *@。 批注可以位于一行或多行:

@*  A one-line code comment. *@

@*
    This is a multiline code comment.
    It can continue for any number of lines.
*@

下面是代码块中的注释:

@{
    @* This is a comment. *@
    var theVar = 17;
}

下面是相同的代码块,其中注释掉了代码行,以便它不会运行:

@{
    @* This is a comment. *@
    @* var theVar = 17;  *@
}

在代码块中,作为使用 Razor 注释语法的替代方法,可以使用所使用的编程语言的注释语法,例如 C#:

@{
    // This is a comment.
    var myVar = 17;
    /* This is a multi-line comment
    that uses C# commenting syntax. */
}

在 C# 中,单行注释前面//有字符,多行注释以/*字符开头和结尾*/。 (与 Razor 注释一样,C# 注释不会呈现到浏览器。

对于标记,如你所知,可以创建 HTML 注释:

<!-- This is a comment.  -->

HTML 注释以字符开头 <!-- ,以结尾 -->。 可以使用 HTML 注释来环绕文本,还可以使用想要保留在页面中但不想呈现的任何 HTML 标记。 此 HTML 注释将隐藏标记的整个内容及其包含的文本:

<!-- <p>This is my paragraph.</p>  -->

与 Razor 注释不同,HTML 注释呈现到页面,用户可以通过查看页面源来查看它们。

Razor 对 C# 的嵌套块有限制。 有关详细信息,请参阅 命名 C# 变量和嵌套块生成中断的代码

变量

变量是用于存储数据的命名对象。 可以命名变量,但名称必须以字母字符开头,并且不能包含空格或保留字符。

变量和数据类型

变量可以具有特定的数据类型,该类型指示存储在变量中的数据类型。 可以具有存储字符串值的字符串变量(如“Hello world”),用于存储整数值的整数变量(如 3 或 79),以及以各种格式存储日期值的日期变量(如 2012/4/12 或 2009 年 3 月)。 可以使用许多其他数据类型。

但是,通常不必为变量指定类型。 大多数情况下,ASP.NET 可以根据变量中的数据的使用方式找出类型。 (有时必须指定一个类型;你将看到示例,其中为 true。

使用 var 关键字(如果不想指定类型)或使用类型的名称声明变量:

@{
    // Assigning a string to a variable.
    var greeting = "Welcome!";

    // Assigning a number to a variable.
    var theCount = 3;

    // Assigning an expression to a variable.
    var monthlyTotal = theCount + 5;

    // Assigning a date value to a variable.
    var today = DateTime.Today;

    // Assigning the current page's URL to a variable.
    var myPath = this.Request.Url;

    // Declaring variables using explicit data types.
    string name = "Joe";
    int count = 5;
    DateTime tomorrow = DateTime.Now.AddDays(1);
}

以下示例演示了网页中变量的一些典型用法:

@{
    // Embedding the value of a variable into HTML markup.
    <p>@greeting, friends!</p>

    // Using variables as part of an inline expression.
    <p>The predicted annual total is: @( monthlyTotal * 12)</p>

    // Displaying the page URL with a variable.
    <p>The URL to this page is: @myPath</p>
}

如果在页面中合并了前面的示例,则会看到此示例显示在浏览器中:

Razor-Img9

转换和测试数据类型

尽管 ASP.NET 通常可以自动确定数据类型,但有时无法确定数据类型。 因此,可能需要通过执行显式转换来帮助 ASP.NET。 即使无需转换类型,有时测试查看可能正在使用的数据类型也很有帮助。

最常见的情况是,必须将字符串转换为另一种类型,例如整数或日期。 以下示例演示了必须将字符串转换为数字的典型情况。

@{
    var total = 0;

    if(IsPost) {
        // Retrieve the numbers that the user entered.
        var num1 = Request["text1"];
        var num2 = Request["text2"];
        // Convert the entered strings into integers numbers and add.
        total = num1.AsInt() + num2.AsInt();
    }
}

作为规则,用户输入以字符串的形式出现。 即使你已提示用户输入数字,即使他们输入了数字,提交用户输入并在代码中读取数字,数据也采用字符串格式。 因此,必须将字符串转换为数字。 在此示例中,如果尝试在不转换值的情况下对值执行算术,则会出现以下错误结果,因为 ASP.NET 无法添加两个字符串:

无法隐式将类型“string”转换为“int”。

若要将值转换为整数,请调用 AsInt 该方法。 如果转换成功,可以添加数字。

下表列出了变量的一些常见转换和测试方法。

方法

描述

示例


AsInt(), IsInt()

将表示整数(如“593”)的字符串转换为整数。

var myIntNumber = 0;
var myStringNum = "539";
if(myStringNum.IsInt()==true){
    myIntNumber = myStringNum.AsInt();
}

AsBool(), IsBool()

将字符串(如“true”或“false”)转换为布尔类型。

var myStringBool = "True";
var myVar = myStringBool.AsBool();

AsFloat(), IsFloat()

将具有小数值的字符串(如“1.3”或“7.439”)转换为浮点数。

var myStringFloat = "41.432895";
var myFloatNum = myStringFloat.AsFloat();

AsDecimal(), IsDecimal()

将具有小数值的字符串(如“1.3”或“7.439”)转换为十进制数。 (在 ASP.NET 中,小数比浮点数更精确。

var myStringDec = "10317.425";
var myDecNum = myStringDec.AsDecimal();

AsDateTime(), IsDateTime()

将表示日期和时间值的字符串转换为 ASP.NET DateTime 类型。

var myDateString = "12/27/2012";
var newDate = myDateString.AsDateTime();

ToString()

将任何其他数据类型转换为字符串。

int num1 = 17;
int num2 = 76;
// myString is set to 1776
string myString = num1.ToString() +
  num2.ToString();

运算符

运算符是一个关键字或字符,指示 ASP.NET 表达式中要执行的命令类型。 C# 语言(和基于它的 Razor 语法)支持许多运算符,但只需识别一些即可开始使用。 下表汇总了最常见的运算符。

Operator

描述

示例


+ - * /

数值表达式中使用的数学运算符。

@(5 + 13)
@{ var netWorth = 150000; }
@{ var newTotal = netWorth * 2; }
@(newTotal / 2)

=

分配。 将语句右侧的值分配给左侧的对象。

var age = 17;

==

相等。 如果值相等,则 true 返回。 (请注意运算符和==运算符之间的区别=

var myNum = 15;
if (myNum == 15) {
    // Do something.
}

!=

不相等。 如果值不相等,则 true 返回。

var theNum = 13;
if (theNum != 15) {
    // Do something.
}

< > <= >=

小于、大于、小于或等于,以及大于或等于。

if (2 < 3) {
    // Do something.
}
var currentCount = 12;
if(currentCount >= 12) {
    // Do something.
}

+

连接,用于联接字符串。 ASP.NET 知道此运算符与基于表达式数据类型的加法运算符之间的差异。

// The displayed result is "abcdef".
@("abc" + "def")

+= -=

递增和递减运算符,它们分别从变量中添加和减去 1。

int theCount = 0;
theCount += 1; // Adds 1 to count

.

点。 用于区分对象及其属性和方法。

var myUrl = Request.Url;
var count = Request["Count"].AsInt();

()

括号。 用于对表达式进行分组,并将参数传递给方法。

@(3 + 7)
@Request.MapPath(Request.FilePath);

[]

括弧。 用于访问数组或集合中的值。

var income = Request["AnnualIncome"];

!

非。 反转一个 truefalse ,反之亦然。 通常用作测试的false速记方法(即不是)。true

bool taskCompleted = false;
// Processing.
if(!taskCompleted) {
    // Continue processing
}

&& ||

逻辑 AND 和 OR,用于将条件链接在一起。

bool myTaskCompleted = false;
int totalCount = 0;
// Processing.
if(!myTaskCompleted && totalCount < 12) {
    // Continue processing.
}

在代码中使用文件和文件夹路径

你通常会在代码中使用文件和文件夹路径。 下面是网站的物理文件夹结构示例,因为它可能显示在开发计算机上:

C:\WebSites\MyWebSite default.cshtml datafile.txt \images Logo.jpg \styles Styles.css

下面是有关 URL 和路径的一些基本详细信息:

  • URL 以域名 (http://www.example.com) 或服务器名称 (http://localhosthttp://mycomputer) 开头。
  • URL 对应于主计算机上的物理路径。 例如, http://myserver 可能与服务器上的文件夹 C:\websites\mywebsite 相对应。
  • 虚拟路径是简写的,表示代码中的路径,而无需指定完整路径。 它包括域或服务器名称后面的 URL 部分。 使用虚拟路径时,可以将代码移动到其他域或服务器,而无需更新路径。

下面是帮助你了解差异的示例:

完整 URL http://mycompanyserver/humanresources/CompanyPolicy.htm
服务器名称 mycompanyserver
虚拟路径 /humanresources/CompanyPolicy.htm
物理路径 C:\mywebsites\humanresources\CompanyPolicy.htm

虚拟根是 /,就像 C: 驱动器的根目录一样。 (虚拟文件夹路径始终使用正斜杠。)文件夹的虚拟路径不必与物理文件夹同名;它可以是别名。 (在生产服务器上,虚拟路径很少与确切的物理路径匹配。

在代码中使用文件和文件夹时,有时需要引用物理路径和虚拟路径,具体取决于所使用的对象。 ASP.NET 提供了用于在代码中使用文件和文件夹路径的工具:方法和Server.MapPath~运算符和Href方法。

将虚拟路径转换为物理路径:Server.MapPath 方法

该方法 Server.MapPath 将虚拟路径(如 /default.cshtml)转换为绝对物理路径(如 C:\WebSites\MyWebSiteFolder\default.cshtml)。 每当需要完整的物理路径时,即可使用此方法。 典型的示例是在 Web 服务器上读取或写入文本文件或图像文件时。

通常你不知道托管站点服务器上的站点的绝对物理路径,因此此方法可以将你知道的路径(虚拟路径)转换为服务器上的相应路径。 将虚拟路径传递到文件或文件夹到方法,并返回物理路径:

@{
    var dataFilePath = "~/dataFile.txt";
}
<!-- Displays a physical path C:\Websites\MyWebSite\datafile.txt  -->
<p>@Server.MapPath(dataFilePath)</p>

引用虚拟根:~ 运算符和 Href 方法

在 .cshtml 或 .vbhtml 文件中,可以使用运算符引用虚拟根路径~。 这非常方便,因为您可以在网站中移动页面,并且它们包含到其他页面的任何链接都不会中断。 如果网站移动到其他位置,也很方便。 以下是一些示例:

@{
    var myImagesFolder = "~/images";
    var myStyleSheet = "~/styles/StyleSheet.css";
}

如果网站是 http://myserver/myapp,以下是页面运行时 ASP.NET 将如何处理这些路径:

  • myImagesFolder: http://myserver/myapp/images
  • myStyleSheet : http://myserver/myapp/styles/Stylesheet.css

(实际上不会将这些路径视为变量的值,但 ASP.NET 将把路径视为它们。

可以在 ~ 服务器代码(如上所示)和标记中使用运算符,如下所示:

<!-- Examples of using the ~ operator in markup in ASP.NET Web Pages -->

<a href="~/Default">Home</a>
<img src="~/images/MyImages.png" />

在标记中 ~ ,使用运算符创建资源的路径,如图像文件、其他网页和 CSS 文件。 当页面运行时,ASP.NET 浏览页面(代码和标记),并解析对相应路径的所有 ~ 引用。

条件逻辑和循环

ASP.NET 服务器代码使你能够基于条件执行任务,并编写代码来重复语句的特定次数(即运行循环的代码)。

测试条件

若要测试使用语句的简单条件 if ,该语句根据指定的测试返回 true 或 false:

@{
  var showToday = true;
  if(showToday)
  {
    @DateTime.Today;
  }
}

关键字 if 启动块。 实际测试(条件)位于括号中,返回 true 或 false。 如果测试为 true,则运行的语句括在大括号中。 如果条件为 false,则 if 语句可以包含一个 else 块,该块指定要运行的语句:

@{
  var showToday = false;
  if(showToday)
  {
    @DateTime.Today;
  }
  else
  {
    <text>Sorry!</text>
  }
}

可以使用块添加多个条件 else if

@{
    var theBalance = 4.99;
    if(theBalance == 0)
    {
        <p>You have a zero balance.</p>
    }
    else if (theBalance  > 0 && theBalance <= 5)
    {
        <p>Your balance of $@theBalance is very low.</p>
    }
    else
    {
        <p>Your balance is: $@theBalance</p>
    }
}

在此示例中,如果块中的第一个条件不为 true,则检查条件 else if 。 如果满足该条件,则执行块中的 else if 语句。 如果未满足任何条件,则执行块中的 else 语句。 可以添加任意数量的其他块(如果块),然后使用块作为“其他所有内容”条件关闭 else

若要测试大量条件,请使用块 switch

@{
    var weekday = "Wednesday";
    var greeting = "";

    switch(weekday)
    {
        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;
        default:
            greeting = "It's some other day, oh well.";
            break;
    }

    <p>Since it is @weekday, the message for today is: @greeting</p>
}

要测试的值在括号中(在本示例中为 weekday 变量)。 每个单独的测试都使用以 case 冒号结尾的语句(:))。 如果语句的值 case 与测试值匹配,则执行该事例块中的代码。 使用语句 break 关闭每个 case 语句。 (如果忘记在每个块中包含 case break,则下一 case 语句中的代码也会运行。如果 switch 其他任何情况都不为 true,则块通常具有 default 语句作为“其他所有内容”选项的最后一种情况。

浏览器中显示的最后两个条件块的结果:

Razor-Img10

循环代码

通常需要重复运行相同的语句。 通过循环执行此操作。 例如,通常针对数据集合中的每个项运行相同的语句。 如果确切地知道要循环的次数,则可以使用 for 循环。 此类循环对于计数或倒计时特别有用:

@for(var i = 10; i < 21; i++)
{
    <p>Line #: @i</p>
}

循环以关键字开头 for ,后跟括号中的三个语句,每个语句以分号结尾。

  • 在括号内,第一个语句 (var i=10;) 将创建一个计数器并将其初始化为 10。 无需为计数器 i 命名 , 即可使用任何变量。 循环 for 运行时,计数器会自动递增。
  • 第二个语句 (i < 21;) 设置要计算的距离的条件。 在这种情况下,你希望它最多转到 20(也就是说,在计数器小于 21 时继续运行)。
  • 第三个语句 (i++ ) 使用递增运算符,它只指定每次循环运行时,计数器应向其添加 1 个。

大括号内是将针对循环的每个迭代运行的代码。 标记每次都会创建一个新段落(<p> 元素),并向输出中添加一行,并显示 (计数器) 的值 i 。 运行此页面时,该示例将创建 11 行,其中显示输出,每行中的文本指示项编号。

Razor-Img11

如果使用集合或数组,则通常使用 foreach 循环。 集合是一组类似的对象, foreach 循环允许对集合中的每个项执行任务。 这种类型的循环对于集合来说很方便,因为与循环不同 for ,你不必递增计数器或设置限制。 相反, foreach 循环代码只会继续完成集合,直到完成。

例如,下面的代码返回集合中的 Request.ServerVariables 项,该集合是包含 Web 服务器相关信息的对象。 它使用 foreac h 循环显示每个项的名称,方法是在 HTML 项目符号列表中创建新 <li> 元素。

<ul>
@foreach (var myItem in Request.ServerVariables)
{
    <li>@myItem</li>
}
</ul>

关键字 foreach 后跟括号,在其中声明一个代表集合中单个项的变量(在示例中 var item),后跟关键字,后跟 in 要循环遍历的集合。 在循环正文 foreach 中,可以使用前面声明的变量访问当前项。

Razor-Img12

若要创建更常规用途的循环,请使用 while 语句:

@{
    var countNum = 0;
    while (countNum < 50)
    {
        countNum += 1;
        <p>Line #@countNum: </p>
    }
}

循环 while 以关键字开头 while ,后跟括号,指定循环的继续时间(此处,只要 countNum 小于 50),然后重复该块。 循环通常递增(添加到)或递减(减去)用于计数的变量或对象。 在此示例中, += 运算符在每次运行循环时都会添加 countNum 1。 (若要在倒计时的循环中递减变量,请使用递减运算符 -=)。

对象和集合

几乎 ASP.NET 网站的所有内容都是一个对象,包括网页本身。 本部分讨论在代码中经常处理的某些重要对象。

页面对象

ASP.NET 中最基本的对象是页面。 无需任何限定对象即可直接访问页面对象的属性。 以下代码使用 Request 页面的对象获取页面的文件路径:

@{
    var path = Request.FilePath;
}

若要明确表示在当前页对象上引用属性和方法,可以选择使用关键字 this 在代码中表示页面对象。 下面是上一个代码示例,其中 this 添加了用于表示页面:

@{
    var path = this.Request.FilePath;
}

可以使用对象的属性 Page 来获取大量信息,例如:

  • Request。 如你所见,这是有关当前请求的信息集合,包括发出请求的浏览器类型、页面的 URL、用户标识等。

  • Response。 这是有关响应(页面)的信息集合,将在服务器代码完成运行时发送到浏览器。 例如,可以使用此属性将信息写入响应中。

    @{
        // Access the page's Request object to retrieve the Url.
        var pageUrl = this.Request.Url;
    }
    <a href="@pageUrl">My page</a>
    

集合对象(数组和字典)

集合是同一类型的对象组,例如数据库中的对象集合Customer。 ASP.NET 包含许多内置集合,如 Request.Files 集合。

你通常会在集合中使用数据。 两种 常见的集合类型是数组字典。 如果要存储类似项的集合,但不想创建单独的变量来保存每个项,则数组非常有用:

@* Array block 1: Declaring a new array using braces. *@
@{
    <h3>Team Members</h3>
    string[] teamMembers = {"Matt", "Joanne", "Robert", "Nancy"};
    foreach (var person in teamMembers)
    {
        <p>@person</p>
    }
}

使用数组,可以声明特定的数据类型,例如 stringintDateTime。 若要指示变量可以包含数组,请将方括号添加到声明(如 string[]int[])。 可以使用数组中的位置(索引)或语句 foreach 访问数组中的项。 数组索引从零开始 ,即第一项位于位置 0,第二项位于位置 1,依此等。

@{
    string[] teamMembers = {"Matt", "Joanne", "Robert", "Nancy"};
    <p>The number of names in the teamMembers array: @teamMembers.Length </p>
    <p>Robert is now in position: @Array.IndexOf(teamMembers, "Robert")</p>
    <p>The array item at position 2 (zero-based) is @teamMembers[2]</p>
    <h3>Current order of team members in the list</h3>
    foreach (var name in teamMembers)
    {
        <p>@name</p>
    }
    <h3>Reversed order of team members in the list</h3>
    Array.Reverse(teamMembers);
    foreach (var reversedItem in teamMembers)
    {
        <p>@reversedItem</p>
    }
}

可以通过获取 Length 数组的属性来确定数组中的项数。 若要获取数组中特定项的位置(要搜索数组),请使用 Array.IndexOf 该方法。 还可以执行诸如反转数组( Array.Reverse 方法)或对内容( Array.Sort 方法)进行排序等操作。

浏览器中显示的字符串数组代码的输出:

Razor-Img13

字典是键/值对的集合,可在其中提供键(或名称)来设置或检索相应的值:

@{
    var myScores = new Dictionary<string, int>();
    myScores.Add("test1", 71);
    myScores.Add("test2", 82);
    myScores.Add("test3", 100);
    myScores.Add("test4", 59);
}
<p>My score on test 3 is: @myScores["test3"]%</p>
@{myScores["test4"] = 79;}
<p>My corrected score on test 4 is: @myScores["test4"]%</p>

若要创建字典,请使用 new 关键字来指示要创建新的字典对象。 可以使用关键字将字典分配给变量 var 。 使用尖括号 () 指示字典中项的数据类型。 < > 在声明结束时,必须添加一对括号,因为实际上这是一个创建新字典的方法。

若要向字典中添加项,可以调用 Add 字典变量的方法(myScores 在本例中),然后指定键和值。 或者,可以使用方括号来指示键并执行简单的赋值,如以下示例所示:

myScores["test4"] = 79;

若要从字典中获取值,请在方括号中指定键:

var testScoreThree = myScores["test3"];

使用参数调用方法

如本文前面所述,您编程的对象可以具有方法。 例如, Database 对象可能有一种方法 Database.Connect 。 许多方法还具有一个或多个参数。 参数是传递给方法的值,使该方法能够完成其任务。 例如,查看方法的 Request.MapPath 声明,该方法采用三个参数:

public string MapPath(string virtualPath, string baseVirtualDir, 
    bool allowCrossAppMapping);

(行已包装,使其更易于阅读。请记住,除了用引号括起来的字符串内外,还可以将换行符放在几乎任何位置。

此方法返回服务器上对应于指定虚拟路径的物理路径。 方法的三个参数是 virtualPathbaseVirtualDirallowCrossAppMapping。 (请注意,在声明中,参数以要接受的数据的数据类型列出。调用此方法时,必须提供所有三个参数的值。

Razor 语法提供了两个选项,用于将参数传递给方法: 位置参数命名参数。 若要使用位置参数调用方法,请按方法声明中指定的严格顺序传递参数。 (通常可以通过阅读方法的文档来了解此顺序。必须遵循顺序,并且不能跳过任何参数 — 如有必要,可以传递空字符串("")或 null 没有值的位置参数。

以下示例假定网站上有一个名为 脚本 的文件夹。 代码调用该方法, Request.MapPath 并按正确的顺序传递三个参数的值。 然后,它显示生成的映射路径。

@{
    // Pass parameters to a method using positional parameters.
    var myPathPositional = Request.MapPath("/scripts", "/", true);
}
<p>@myPathPositional</p>

当方法具有许多参数时,可以使用命名参数使代码更易于阅读。 若要使用命名参数调用方法,请指定参数名称后跟冒号(:),然后指定值)。 命名参数的优点是可以按所需的任何顺序传递它们。 (缺点是方法调用不那么紧凑。

以下示例调用与上述方法相同的方法,但使用命名参数来提供值:

@{
    // Pass parameters to a method using named parameters.
    var myPathNamed = Request.MapPath(baseVirtualDir: "/", 
        allowCrossAppMapping: true, virtualPath: "/scripts");
}
<p>@myPathNamed</p>

如你所看到的,参数按不同的顺序传递。 但是,如果运行前面的示例和此示例,它们将返回相同的值。

处理错误

Try-Catch 语句

通常,代码中有一些语句,这些语句可能会因控件外部的原因而失败。 例如:

  • 如果代码尝试创建或访问文件,则可能会发生各种错误。 所需的文件可能不存在,它可能被锁定,代码可能没有权限,等等。
  • 同样,如果代码尝试更新数据库中的记录,则可能存在权限问题,可能会删除与数据库的连接,保存的数据可能无效,等等。

在编程术语中,这些情况称为 异常。 如果代码遇到异常,它会生成一条错误消息(至少会对用户产生恼火):

Razor-Img14

如果代码可能会遇到异常,并且为了避免出现此类型的错误消息,可以使用 try/catch 语句。 在 try 语句中,运行要检查的代码。 在一个或多个 catch 语句中,可以查找可能发生的特定错误(特定类型的异常)。 可以根据需要包含任意数量的 catch 语句来查找预期的错误。

注意

建议避免 Response.Redirect 在语句中使用 try/catch 该方法,因为它可能会导致页面中出现异常。

以下示例显示一个页面,该页面在第一个请求上创建文本文件,然后显示一个按钮,允许用户打开该文件。 该示例故意使用错误的文件名,以便会导致异常。 该代码包含 catch 两个可能异常的语句: FileNotFoundException如果文件名不正确,则会发生,如果 DirectoryNotFoundExceptionASP.NET 甚至找不到文件夹,则会发生此情况。 (可以在示例中取消注释语句,以查看它在一切正常运行时如何运行。

如果代码未处理异常,会看到类似于上一个屏幕截图的错误页。 但是,该 try/catch 部分有助于防止用户看到这些类型的错误。

@{
    var dataFilePath = "~/dataFile.txt";
    var fileContents = "";
    var physicalPath = Server.MapPath(dataFilePath);
    var userMessage = "Hello world, the time is " + DateTime.Now;
    var userErrMsg = "";
    var errMsg = "";

    if(IsPost)
    {
        // When the user clicks the "Open File" button and posts
        // the page, try to open the created file for reading.
        try {
            // This code fails because of faulty path to the file.
            fileContents = File.ReadAllText(@"c:\batafile.txt");

            // This code works. To eliminate error on page,
            // comment the above line of code and uncomment this one.
            //fileContents = File.ReadAllText(physicalPath);
        }
        catch (FileNotFoundException ex) {
            // You can use the exception object for debugging, logging, etc.
            errMsg = ex.Message;
            // Create a friendly error message for users.
            userErrMsg = "A file could not be opened, please contact "
                + "your system administrator.";
        }
        catch (DirectoryNotFoundException ex) {
            // Similar to previous exception.
            errMsg = ex.Message;
            userErrMsg = "A directory was not found, please contact "
                + "your system administrator.";
        }
    }
    else
    {
        // The first time the page is requested, create the text file.
        File.WriteAllText(physicalPath, userMessage);
    }
}

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>Try-Catch Statements</title>
    </head>
    <body>
    <form method="POST" action="" >
      <input type="Submit" name="Submit" value="Open File"/>
    </form>

    <p>@fileContents</p>
    <p>@userErrMsg</p>

    </body>
</html>

其他资源

使用 Visual Basic 编程

附录:Visual Basic 语言和语法

参考文档

ASP.NET

C# 语言