Introduction to ASP.NET Web Programming Using the Razor Syntax (Visual Basic)(使用 Razor 语法的 ASP.NET Web 编程简介 (Visual Basic))

作者 Tom FitzMacken

本文概述了使用 Razor 语法和 Visual Basic 通过 ASP.NET 网页 进行编程。 ASP.NET 是 Microsoft 用于在 Web 服务器上运行动态网页的技术。

你将了解的内容

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

软件版本

  • ASP.NET 网页 (Razor) 3

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

将 ASP.NET 网页 与 Razor 语法结合使用的大多数示例都使用 C#。 但 Razor 语法也支持 Visual Basic。 若要在 Visual Basic 中对 ASP.NET 网页进行编程,请使用 .vbhtml 文件扩展名创建网页,然后添加 Visual Basic 代码。 本文概述了如何使用 Visual Basic 语言和语法来创建 ASP.NET 网页。

注意

Microsoft WebMatrix (BakeryPhoto GalleryStarter Site 等的默认网站模板) 在 C# 和 Visual Basic 版本中可用。 可以通过将 Visual Basic 模板作为 NuGet 包进行安装。 网站模板安装在名为 Microsoft Templates 的文件夹中网站的根文件夹中。

前 8 个编程提示

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

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

字符 @ 以内联表达式、单语句块和多语句块开头:

<!-- Single statement blocks  -->
@Code  Dim total = 7  End Code
@Code  Dim myMessage = "Hello World" End Code

<!-- Inline expressions -->
<p>The value of your account is: @total </p>
<p>The value of myMessage is: @myMessage</p>        
    
<!-- Multi-statement block -->    
@Code 
    Dim greeting = "Welcome to our site!"
    Dim weekDay = DateTime.Now.DayOfWeek
    Dim greetingMessage = greeting & " Today is: " & weekDay.ToString()
End Code 
<p>The greeting is: @greetingMessage</p>

浏览器中显示的结果:

Razor-Img1

提示

HTML 编码

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

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

有关 HTML 编码的详细信息,请参阅在 ASP.NET 网页 网站中使用 HTML 表单

2. 使用代码将代码块括起来...结束代码

代码块包含一个或多个代码语句,并用关键字 CodeEnd Code括起来。 将开头Code关键字 (keyword) 紧跟在@字符后面, 它们之间不能有空格。

<!-- Single statement block.  -->
@Code
    Dim theMonth = DateTime.Now.Month
End Code
<p>The numeric value of the current month: @theMonth</p>

<!-- Multi-statement block. -->
@Code
    Dim outsideTemp = 79
    Dim weatherMessage = "Hello, it is " & outsideTemp & " degrees."
End Code 
<p>Today's weather: @weatherMessage</p>

浏览器中显示的结果:

Razor-Img2

3. 在 块内,使用换行符结束每个代码语句

在 Visual Basic 代码块中,每个语句以换行符结尾。 (稍后在文章中,你将看到一种在需要时将长代码语句包装成多行的方法。)

<!-- Single statement block. -->
@Code
    Dim theMonth = DateTime.Now.Month
End Code

<!-- Multi-statement block. -->
@Code
    Dim outsideTemp = 79
    Dim weatherMessage = "Hello, it is " & outsideTemp & " degrees."
End Code 

<!-- An inline expression, so no line break needed. -->
<p>Today's weather: @weatherMessage</p>

4.使用变量存储值

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

<!-- Storing a string -->
@Code 
    Dim welcomeMessage = "Welcome, new members!"
End Code
<p>@welcomeMessage</p>
    
<!-- Storing a date -->
@Code 
    Dim year = DateTime.Now.Year
End Code

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

浏览器中显示的结果:

Razor-Img3

5.将文本字符串值括在双引号中

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

@Code 
    Dim myString = "This is a string literal"
End Code

若要在字符串值中嵌入双引号,请插入两个双引号字符。 如果希望双引号字符在页面输出中出现一次,请在带引号的字符串中输入 "" ,如果希望它出现两次,请在带引号的字符串中输入 """"

<!-- Embedding double quotation marks in a string -->
@Code 
    Dim myQuote = "The person said: ""Hello, today is Monday."""
End Code
<p>@myQuote</p>

浏览器中显示的结果:

Razor-Img4

6. Visual Basic 代码不区分大小写

Visual Basic 语言不区分大小写。 编程关键字 ((如 DimIfTrue) )以及变量名称 ((如 myString)或 subTotal) 在任何情况下都可以编写。

以下代码行使用小写名称为变量 lastname 赋值,然后使用大写名称将变量值输出到页面。

@Code 
    Dim lastName = "Smith"
    ' Keywords like dim are also not case sensitive.
    DIM someNumber = 7
End Code
<p>The value of the <code>lastName</code> variable is: @LASTNAME</p>

浏览器中显示的结果:

vb-syntax-5

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 语句) 。

@Code
   Dim result = ""
   If IsPost Then
      result = "This page was posted using the Submit button."
   Else
      result = "This was the first request for this page."
   End If
End Code
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>Write Code that Makes Decisions</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.vbhtml

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

    @Code
        Dim total = 0
        Dim totalMessage = ""
        if IsPost Then
            ' Retrieve the numbers that the user entered.
            Dim num1 = Request("text1")
            Dim num2 = Request("text2")
            ' Convert the entered strings into integers numbers and add.
            total = num1.AsInt() + num2.AsInt()
            totalMessage = "Total = " & total
        End If
    End Code
    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="utf-8" />
            <title>Adding Numbers</title>
            <style type="text/css">
                body {background-color: beige; font-family: Verdana, Ariel; 
                    margin: 50px;
                    }
                form {padding: 10px; border-style: solid; width: 250px;}
            </style>
        </head>
    <body>
        <p>Enter two whole numbers and click <strong>Add</strong> to display the result.</p>
        <p></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 变量之前。
    • 页面顶部的 块包含在 中 Code...End Code
    • 变量 totalnum1num2totalMessage 存储多个数字和一个字符串。
    • 分配给 totalMessage 变量的文本字符串值用双引号引起来。
    • 由于 Visual Basic 代码不区分大小写,因此在 totalMessage 页面底部附近使用该变量时,其名称只需与页面顶部变量声明的拼写相匹配。 大小写并不重要。
    • 表达式 num1.AsInt() + num2.AsInt() 演示如何使用对象和方法。 AsInt每个变量上的 方法将用户输入的字符串转换为整数 (可添加的整数) 。
    • 标记 <form> 包含 属性 method="post" 。 这指定当用户单击“ 添加”时,将使用 HTTP POST 方法将页面发送到服务器。 提交页面时,代码 If IsPost 的计算结果为 true,条件代码运行,显示数字相加的结果。
  3. 保存页面并在浏览器中运行它。 (在运行页面之前,请确保已在 “文件” 工作区中选择该页。) 输入两个整数,然后单击“ 添加 ”按钮。

    Razor-Img7

Visual Basic 语言和语法

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

如果你具有编程 (经验,尤其是在使用过 C、C++、C#、Visual Basic 或 JavaScript) 的情况下,你在此处阅读的大部分内容都会很熟悉。 你可能只需要熟悉如何将 WebMatrix 代码添加到 .vbhtml 文件中的标记。

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

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

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

    @If IsPost Then
        ' 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: </p> @DateTime.Now
    End If
    

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

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

    @If IsPost Then
        ' Plain text followed by an unmatched HTML tag and server code.
        @:The time is: <br /> @DateTime.Now
        ' Server code and then plain text, matched tags, and more text.
        @DateTime.Now @:is the <em>current</em> time.
    End If
    

    以下示例重复前面的示例,但使用一对 <text> 标记将要呈现的文本括起来。

    @If IsPost Then
        @<text>
        The time is: <br /> @DateTime.Now
        @DateTime.Now is the <em>current</em> time.
        </text>
    End If
    

    在下面的示例中 <text> , 和 </text> 标记包含三行,所有这些行都有一些未包含的文本和不匹配的 HTML 标记 (<br />) ,以及服务器代码和匹配的 HTML 标记。 同样,还可以在每一行前面分别使用 @: 运算符;任一方式都有效。

    @Code
        dim minTemp = 75 
        @<text>It is the month of @DateTime.Now.ToString("MMMM"), and  
        it's a <em>great</em> day! <p>You can go swimming if it's at 
        least @minTemp degrees.</p></text>
    End Code
    

    注意

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

空格

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

@Code Dim personName =    "Smith"    End Code

将长语句分解为多行

可以使用下划线字符 _ (将长代码语句拆分为多行,在 Visual Basic 中,每行代码后称为 延续字符) 。 若要将 语句中断到下一行,请在行的末尾添加空格,然后添加延续字符。 继续下一行的 语句。 你可以根据需要将语句包装到任意数量的行上,以提高可读性。 下列语句相同:

@Code
    Dim familyName _
    =  "Smith" 
End Code

@Code
    Dim _
    theName _
    = _
    "Smith"
End Code

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

@Code 
    ' Doesn't work.
    Dim test = "This is a long _
      string"
End Code

若要合并一个换行到多行的长字符串(如上述代码),需要使用 串联运算符 (&) ,本文稍后将介绍。

代码注释

批注允许你为自己或他人留下笔记。 Razor 语法注释的前缀为 @* ,以 结尾 *@

@* A single-line comment is added like this example. *@
    
@*
    This is a multiline code comment. 
    It can continue for any number of lines.
*@

在代码块中,可以使用 Razor 语法注释,也可以使用普通的 Visual Basic 注释字符,即单引号 (' 每行) 前缀。

@Code
    ' You can make comments in blocks by just using ' before each line.
End Code
    
@Code
    ' There is no multi-line comment character in Visual Basic. 
    ' You use a ' before each line you want to comment. 
End Code

变量

变量是用于存储数据的命名对象。 你可以为变量命名任何内容,但名称必须以字母字符开头,并且不能包含空格或保留字符。 如前所述,在 Visual Basic 中,变量名称中的字母大小写并不重要。

变量和数据类型

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

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

若要声明变量而不指定类型,请使用 Dim 变量名称 (例如 Dim myVar ,) 。 若要使用 类型声明变量,请使用 Dim 加上变量名称,后跟 As 类型名称,然后 (类型名称,例如 Dim myVar As String ,) 。

@Code
    ' Assigning a string to a variable.
    Dim greeting = "Welcome" 
    
    ' Assigning a number to a variable.
    Dim theCount = 3
    
    ' Assigning an expression to a variable.
    Dim monthlyTotal = theCount + 5
    
    ' Assigning a date value to a variable.
    Dim today = DateTime.Today
    
    ' Assigning the current page's URL to a variable.
    Dim myPath = Request.Url
    
    ' Declaring variables using explicit data types.
    Dim name as String = "Joe"
    Dim count as Integer = 5
    Dim tomorrow as DateTime = DateTime.Now.AddDays(1)
End Code

以下示例显示了一些在网页中使用变量的内联表达式。

@Code
    ' Embedding the value of a variable into HTML markup.
    ' Precede the markup with @ because we are in a code block.
    @<p>@greeting, friends!</p>
End Code

<!-- Using a variable with an inline expression in HTML. --> 
<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。 即使不必转换类型,有时测试以查看可能正在使用的数据类型也很有帮助。

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

@Code
    Dim total = 0
    Dim totalMessage = ""
    if IsPost Then
        ' Retrieve the numbers that the user entered.
        Dim num1 = Request("text1")
        Dim num2 = Request("text2")
        ' Convert the entered strings into integers numbers and add.
        total = num1.AsInt() + num2.AsInt()
        totalMessage = "Total = " & total
    End If
End Code

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

Cannot implicitly convert type 'string' to 'int'.

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

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

方法

说明

示例


AsInt(), IsInt()

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

Dim myIntNumber = 0
Dim myStringNum = "539"
If myStringNum.IsInt() Then
    myIntNumber = myStringNum.AsInt()
End If

AsBool(), IsBool()

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

Dim myStringBool = "True"
Dim myVar = myStringBool.AsBool()

AsFloat(), IsFloat()

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

Dim myStringFloat = "41.432895"
Dim myFloatNum = myStringFloat.AsFloat()

AsDecimal(), IsDecimal()

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

Dim myStringDec = "10317.425"
Dim myDecNum = myStringDec.AsDecimal()

AsDateTime(), IsDateTime()

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

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

ToString()

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

Dim num1 As Integer = 17
Dim num2 As Integer = 76

' myString is set to 1776
Dim myString as String = num1.ToString() & _
    num2.ToString()

运算符

运算符是一个关键字 (keyword) 或字符,告诉 ASP.NET 在表达式中执行哪种类型的命令。 Visual Basic 支持许多运算符,但只需识别几个运算符即可开始开发 ASP.NET 网页。 下表汇总了最常见的运算符。

“运算符”

说明

示例


+ - * /

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

@(5 + 13)

Dim netWorth = 150000
Dim newTotal = netWorth * 2
@(newTotal / 2)

=

赋值和相等性。 根据上下文,将语句右侧的值分配给左侧的对象,或检查值是否相等。

Dim age = 17

Dim income = Request("AnnualIncome")

<>

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

Dim theNum = 13
If theNum <> 15 Then
    ' Do something.
End If

< > <= >=

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

If 2 < 3 Then
    ' Do something.
End If

Dim currentCount = 12
If currentCount >= 12 Then
    ' Do something.
End If

&

串联,用于联接字符串。

' The displayed result is "abcdef".
@("abc" & "def")

+= -=

增量和递减运算符,分别从变量) 加减 1 (。

Dim theCount As Integer = 0
theCount += 1 ' Adds 1 to count

.

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

Dim myUrl = Request.Url
Dim count = Request("Count").AsInt()

()

括号。 用于对表达式进行分组、将参数传递给方法以及访问数组和集合的成员。

@(3 + 7)

@Request.MapPath(Request.FilePath)

Not

非。 将 true 值反转为 false,反之亦然。 通常用作测试 False (的速记方法,即,对于非 True) 。

Dim taskCompleted As Boolean = False
' Processing.
If Not taskCompleted Then 
    ' Continue processing
End If

AndAlso OrElse

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

Dim myTaskCompleted As Boolean = false
Dim totalCount As Integer = 0          
' Processing.
If (Not myTaskCompleted) AndAlso _
         totalCount < 12 Then 
    ' Continue processing.
End If

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

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

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

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

  • URL 以) (http://www.example.com 域名或服务器名称 (http://localhost开头, http://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 服务器上读取或写入文本文件或图像文件时。

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

@Code
    Dim dataFilePath = "~/dataFile.txt"
End Code    

<!-- Displays a physical path C:\Websites\MyWebSite\datafile.txt  --> 
<p>@Server.MapPath(dataFilePath)</p>

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

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

@Code
    Dim myImagesFolder = "~/images"
    Dim myStyleSheet = "~/styles/StyleSheet.css"       
End Code

如果网站为 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...Then 请使用 语句,该语句返回 TrueFalse 基于指定的测试:

@Code
    Dim showToday = True
    If showToday Then
        DateTime.Today
    End If
End Code

关键字 (keyword) If 启动块。 实际测试 (条件) 遵循If关键字 (keyword) 并返回 true 或 false。 语句 IfThen结尾。 如果测试为 true,将运行的语句由 IfEnd If括起来。 语句 If 可以包含一个 Else 块,该块指定要在条件为 false 时运行的语句:

@Code
    Dim showToday = False
    If showToday Then
        DateTime.Today
    Else
        @<text>Sorry!</text>
    End If
End Code

如果语句 If 启动代码块,则无需使用普通 Code...End Code 语句来包括这些块。 只需将 添加到 @ 块中,即可正常工作。 此方法适用于 If 其他 Visual Basic 编程关键字,这些关键字后跟代码块,包括 ForFor EachDo While等。

@If showToday Then
    DateTime.Today
Else
    @<text>Sorry!</text>
End If

可以使用一个或多个 ElseIf 块添加多个条件:

@Code
    Dim theBalance = 4.99
    If theBalance = 0 Then
        @<p>You have a zero balance.</p>
    ElseIf theBalance > 0 AndAlso theBalance <= 5 Then
        ' If the balance is above 0 but less than
        ' or equal to $5, display this message.
        @<p>Your balance of $@theBalance is very low.</p>
    Else
        ' For balances greater than $5, display balance.
        @<p>Your balance is: $@theBalance</p>
    End If    
End Code

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

若要测试大量条件,请使用 Select Case 块:

@Code
    Dim weekday = "Wednesday"
    Dim greeting = ""
    
    Select Case weekday
        Case "Monday"
            greeting = "Ok, it's a marvelous Monday."
        Case "Tuesday"
            greeting = "It's a tremendous Tuesday."
        Case "Wednesday"
            greeting = "Wild Wednesday is here!"
        Case Else
            greeting = "It's some other day, oh well."
    End Select
End Code
<p>Since it is @weekday, the message for today is: @greeting</p>

要测试的值位于示例中的括号 (,即工作日变量) 。 每个单独的测试都使用一个 Case 语句来列出一个值。 如果语句的值 Case 与测试值匹配,则会执行该 Case 块中的代码。

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

Razor-Img10

循环代码

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

@For i = 10 To 20
    @<p>Item #: @i</p>
Next i

循环以For关键字 (keyword) 开头,后跟三个元素:

  • 紧接在 For 语句之后,声明一个计数器变量 (无需使用 Dim) ,然后指示范围,如 中所示 i = 10 to 20。 这意味着变量 i 将从 10 开始计数,并一直持续到达到 20 (非独占) 。
  • ForNext 语句之间是块的内容。 这可以包含一个或多个与每个循环一起执行的代码语句。
  • 语句 Next i 结束循环。 它会递增计数器,并开始循环的下一次迭代。

Next 行之间的For代码行包含为循环的每个迭代运行的代码。 标记每次) <p> (元素创建一个新段落,并在输出中添加一行, (计数器) 显示 i 的值。 运行此页面时,该示例创建 11 行显示输出,每行中的文本指示项编号。

Razor-Img11

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

此示例返回集合中的项 Request.ServerVariables (其中包含有关 Web 服务器) 的信息。 它使用 For Each 循环通过在 HTML 项目符号列表中创建新 <li> 元素来显示每个项的名称。

<ul>
@For Each myItem In Request.ServerVariables
    @<li>@myItem</li>
Next myItem
</ul>

For Each 关键字 (keyword) 后跟一个变量,该变量代表集合 (示例中的单个项, myItem) ,后跟In关键字 (keyword) ,后跟要循环访问的集合。 在循环的正文中 For Each ,可以使用前面声明的 变量访问当前项。

Razor-Img12

若要创建更通用的循环,请使用 Do While 语句:

@Code
    Dim countNum = 0
    Do While countNum < 50
        countNum += 1
        @<p>Line #@countNum: </p>
    Loop
End Code

此循环以关键字 (keyword) 开始Do While,后跟条件,后跟要重复的块。 循环通常递增 (添加到) 或递减, (从用于计数的变量或对象) 减去。 在示例中,每次运行循环时, += 运算符都会向变量的值添加 1。 (若要在倒计时的循环中递减变量,请使用递减运算符 -=.)

对象和集合

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

Page 对象

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

@Code
    Dim path = Request.FilePath
End Code

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

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

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

    @Code
        ' Access the page's Request object to retrieve the URL.
        Dim pageUrl = Request.Url
    End Code
        <a href="@pageUrl">My page</a>
    

集合对象 (数组和字典)

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

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

<h3>Team Members</h3>
@Code
    Dim teamMembers() As String = {"Matt", "Joanne", "Robert", "Nancy"}
    For Each name In teamMembers
        @<p>@name</p>
    Next name
End Code

使用数组,可以声明特定的数据类型,例如 StringIntegerDateTime。 若要指示变量可以包含数组,请将括号添加到声明 (中的变量名称,例如 Dim myVar() As String) 。 可以使用数组中项的位置 (索引) 或使用 语句来访问项 For Each 。 数组索引是从零开始的,也就是说,第一项位于位置 0,第二项位于位置 1,依此而行。

@Code
    Dim teamMembers() As String = {"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>
    For Each name In teamMembers
        @<p>@name</p>
    Next name
    @<h3>Reversed order of team members in the list</h3>
    Array.Reverse(teamMembers)
    For Each reversedItem In teamMembers
        @<p>@reversedItem</p>
    Next reversedItem
End Code

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

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

Razor-Img13

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

@Code
    Dim myScores = New Dictionary(Of String, Integer)()
    myScores.Add("test1", 71)
    myScores.Add("test2", 82)
    myScores.Add("test3", 100)
    myScores.Add("test4", 59)
End Code
<p>My score on test 3 is: @myScores("test3")%</p>
@Code 
    myScores("test4") = 79
End Code
<p>My corrected score on test 4 is: @myScores("test4")%</p>

若要创建字典,请使用New关键字 (keyword) 来指示正在创建新Dictionary对象。 可以使用 关键字 (keyword) 将字典分配给变量Dim。 使用括号 ( ( ) ) 指示字典中项的数据类型。 在声明的末尾,必须添加另一对括号,因为这实际上是创建新字典的方法。

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

@Code
    myScores("test4") = 79
End Code

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

@myScores("test4")

使用参数调用方法

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

Public Overridable Function MapPath (virtualPath As String, _
    baseVirtualDir As String, _
    allowCrossAppMapping As Boolean)

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

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

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

@Code
    ' Pass parameters to a method using positional parameters.
    Dim myPathPositional = Request.MapPath("/scripts", "/", true)
End Code
<p>@myPathPositional</p>

当方法有多个参数时,可以使用命名参数使代码更简洁、更易于阅读。 若要使用命名参数调用方法,请指定后跟 := 的参数名称,然后提供值。 命名参数的优点是可以按所需的任何顺序添加它们。 (一个缺点是方法调用不如 compact.)

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

@Code
    ' Pass parameters to a method using named parameters.
    Dim myPathNamed = Request.MapPath(baseVirtualDir:= "/", allowCrossAppMapping:= true, virtualPath:= "/scripts")
End Code
<p>@myPathNamed</p>

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

处理错误

Try-Catch 语句

代码中通常会有语句,这些语句可能因不受控制的原因而失败。 例如:

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

在编程术语中,这些情况称为 异常。 如果代码遇到异常,则会生成 (引发) 错误消息,充其量是让用户恼火的。

Razor-Img14

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

注意

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

以下示例显示了一个页面,该页面在第一个请求中创建一个文本文件,然后显示一个允许用户打开该文件的按钮。 该示例故意使用错误的文件名,以便导致异常。 该代码包含 Catch 两个可能异常的语句: FileNotFoundException(在文件名错误时发生)和 DirectoryNotFoundException(在 ASP.NET 甚至找不到文件夹时发生)。 (可以取消注释示例中的语句,以查看当一切正常时它的运行方式。)

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

@Code
    Dim dataFilePath = "~/dataFile.txt"
    Dim fileContents = ""
    Dim physicalPath = Server.MapPath(dataFilePath)
    Dim userMessage = "Hello world, the time is " + DateTime.Now
    Dim userErrMsg = ""
    Dim errMsg = ""
    
    If IsPost Then
        ' When the user clicks the "Open File" button and posts
        ' the page, try to open the file.
        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 ex As FileNotFoundException
            ' You can use the exception object for debugging, logging, etc.
            errMsg = ex.Message
            ' Create a friendly error message for users.
            userErrMsg = "The file could not be opened, please contact " _
                & "your system administrator."
                
        Catch ex As DirectoryNotFoundException
            ' Similar to previous exception.
            errMsg = ex.Message
            userErrMsg = "The file could not be opened, please contact " _
                & "your system administrator."
        End Try
    Else
        ' The first time the page is requested, create the text file.
        File.WriteAllText(physicalPath, userMessage)
    End If
End Code
<!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>

其他资源

参考文档