通过


使用 Razor 语法 ASP.NET Web 编程简介 (Visual Basic)

作者: Tom FitzMacken

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

你将了解的内容

  • 入门使用 Razor 语法进行 ASP.NET 网页编程的 8 个重要提示。
  • 需要的基本编程概念。
  • ASP.NET 服务器代码和 Razor 语法是什么。

软件版本

  • ASP.NET 网页程序(Razor)3

本教程也适用于 ASP.NET Web Pages 2。

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

注释

C# 和 Visual Basic 版本中提供了用于 Microsoft WebMatrix(面包店照片库初学者网站等)的默认网站模板。 可以将 Visual Basic 模板作为 NuGet 包安装。 网站模板安装在网站根文件夹中,该文件夹名为 Microsoft模板

前 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 编码,服务器代码的输出可能无法正确显示,并可能使页面暴露于安全风险之中。

如果你的目标是输出显示 HTML 标签本身的标记(例如段落用<p></p>,强调文本用<em></em>),请参阅本文稍后的在代码块中组合文本、标记和代码部分。

您可以在 ASP.NET Web Pages 网站中的《在 ASP.NET 网页中处理 HTML 表单》一文中阅读有关 HTML 编码的更多信息。

2.将代码块与代码括起来...结束代码

代码块包含一个或多个代码语句,并由关键字 CodeEnd Code 包围。 将 Code 关键字紧跟在 @ 字符后面,它们之间不能有空格。

<!-- 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 关键字创建新变量。 可以在页面中使用 @ 直接插入变量值。

<!-- 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)和变量名称(如 myStringsubTotal)可以使用任意大小写书写。

以下代码行使用小写名称向变量 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 中。
    • 变量 totalnum1变量 num2totalMessage 存储多个数字和字符串。
    • 分配给 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

Variables

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

变量和数据类型

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

但是,无需为变量指定类型。 在大多数情况下,ASP.NET 可以根据变量中的数据的使用方式找出类型。 有时必须指定一个类型,你会看到一些需要这样做的示例。

若要在不指定类型的情况下声明变量,请使用 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()

运营商

运算符是一个关键字或字符,指示 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://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 服务器上读取或写入文本文件或图像文件时。

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

@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

关键字 If 开始一个块。 实际测试(条件)遵循 If 关键字并返回 true 或 false。 语句IfThen结尾。 如果测试为 true,则将运行的语句被IfEnd If包围。 如果条件为 false,则 If 语句可以包含一个 Else 块,该块指定要运行的语句:

@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 ,后跟三个元素:

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

ForNext 之间的代码行包含在循环的每次迭代中运行的代码。 每次标记都会创建一个新的段落(<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 后跟一个代表集合中单个项的变量(例如 myItem),然后是关键字 In,之后跟要循环访问的集合。 在循环正文 For Each 中,可以使用前面声明的变量访问当前项。

Razor-Img12

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

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

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

对象和集合

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

页面对象

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 关键字指示要创建新 Dictionary 对象。 可以使用关键字将字典分配给变量 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。

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

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

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

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

@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 异常;如果 ASP.NET 连文件夹都找不到,会发生 DirectoryNotFoundException 异常。 可以在示例中将语句解除注释,以查看它在一切正常运行时的表现。)

如果代码未处理异常,会看到类似于上一个屏幕截图的错误页。 但是,该 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>

其他资源

参考文档