作者: 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>
结果显示在浏览器中:
小窍门
HTML 编码
使用 @ 字符在页面中显示内容时,如前面的示例所示,ASP.NET HTML 编码输出。 这会将保留的 HTML 字符(如 <、> 和 &)替换为代码,使这些字符可在网页中显示为字符,而不是被解析为 HTML 标签或实体。 如果没有 HTML 编码,服务器代码的输出可能无法正确显示,并可能使页面暴露于安全风险之中。
如果你的目标是输出显示 HTML 标签本身的标记(例如段落用<p></p>,强调文本用<em></em>),请参阅本文稍后的在代码块中组合文本、标记和代码部分。
您可以在 ASP.NET Web Pages 网站中的《在 ASP.NET 网页中处理 HTML 表单》一文中阅读有关 HTML 编码的更多信息。
2.将代码块与代码括起来...结束代码
代码块包含一个或多个代码语句,并由关键字 Code 和 End 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>
结果显示在浏览器中:
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>
结果显示在浏览器中:
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>
结果显示在浏览器中:
6. Visual Basic 代码不区分大小写
Visual Basic 语言不区分大小写。 编程关键字(如 Dim、If 和 True)和变量名称(如 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>
结果显示在浏览器中:
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>
结果显示在浏览器中:
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 语句,还有各种方法来测试条件、重复代码块等,本文稍后将对此进行介绍。
结果显示在浏览器中(单击 “提交”后):
小窍门
HTTP GET 和 POST 方法和 IsPost 属性
用于网页(HTTP)的协议支持用于向服务器发出请求的方法(“谓词”)数量非常有限。 最常见的两个是 GET,用于读取页面,POST 用于提交页面。 通常,用户第一次请求页面时,将使用 GET 请求页面。 如果用户填写表单,然后单击“ 提交”,浏览器会向服务器发出 POST 请求。
在 Web 编程中,了解页面是作为 GET 请求还是 POST,以便知道如何处理页面,这通常很有用。 在 ASP.NET 网页中,可以使用 IsPost 该属性来查看请求是 GET 还是 POST。 如果请求是 POST,则 IsPost 属性将返回 true,你可以执行诸如读取窗体上文本框的值之类的操作。 你会看到许多示例展示如何根据 IsPost 的值以不同的方式处理页面。
简单代码示例
此过程演示如何创建说明基本编程技术的页面。 在本示例中,你将创建一个页面,允许用户输入两个数字,然后添加它们并显示结果。
在编辑器中,创建新的文件并将其命名为 AddNumbers.vbhtml。
将以下代码和标记复制到页面中,替换页面中已有的任何内容。
@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中。 - 变量
total、num1变量num2和totalMessage存储多个数字和字符串。 - 分配给
totalMessage变量的文本字符串值采用双引号。 - 由于 Visual Basic 代码不区分大小写,因此当
totalMessage变量在页面底部附近使用时,其名称只需与页面顶部的变量声明的拼写匹配。 大小写并不重要。 -
num1.AsInt()+num2.AsInt()表达式演示如何使用对象和方法。AsInt每个变量上的方法将用户输入的字符串转换为可添加的整数(整数)。 - 标记
<form>包括一个method="post"属性。 这指定当用户单击 “添加”时,将使用 HTTP POST 方法将页面发送到服务器。 提交页面后,代码If IsPost的计算结果为 true,条件代码运行,显示添加数字的结果。
- 该
保存页面并在浏览器中运行。 (在运行页面之前,请确保在 “文件” 工作区中选择该页面。输入两个整数,然后单击“ 添加 ”按钮。
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 IfHTML 元素可以包括文本、其他 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>
结果显示在浏览器中:
转换和测试数据类型
尽管 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://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 语句,该语句会根据您指定的测试返回 True 或 False。
@Code
Dim showToday = True
If showToday Then
DateTime.Today
End If
End Code
关键字 If 开始一个块。 实际测试(条件)遵循 If 关键字并返回 true 或 false。 语句If以Then结尾。 如果测试为 true,则将运行的语句被If和End 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 编程关键字,包括 For、For Each、Do 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 块中的代码。
浏览器中显示的最后两个条件块的结果:
循环代码
通常需要重复运行相同的语句。 通过循环执行此操作。 例如,通常针对数据集合中的每个项运行相同的语句。 如果确切地知道要循环的次数,则可以使用 For 循环。 此类循环对于计数或倒计时特别有用:
@For i = 10 To 20
@<p>Item #: @i</p>
Next i
循环以关键字开头 For ,后跟三个元素:
- 紧接在
For语句之后,立即声明计数器变量(无需使用Dim),然后指示范围,如i = 10 to 20所示。 这意味着变量i将开始计数为 10,并继续,直到达到 20(含)。 -
For和Next语句之间是块的内容。 这可以包含一个或多个使用每个循环执行的代码语句。 - 该
Next i语句结束循环。 它会递增计数器并启动循环的下一次迭代。
For 和 Next 之间的代码行包含在循环的每次迭代中运行的代码。 每次标记都会创建一个新的段落(<p> 元素),并向输出中添加一行,显示 i(计数器)的值。 运行此页面时,该示例将创建 11 行,其中显示输出,每行中的文本指示项编号。
如果使用集合或数组,则通常使用 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 中,可以使用前面声明的变量访问当前项。
若要创建更常规用途的循环,请使用 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
使用数组,可以声明特定的数据类型,例如 String, Integer或 DateTime。 若要指示变量可以包含数组,请将括号添加到声明中的变量名称(例如 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 方法)进行排序等操作。
浏览器中显示的字符串数组代码的输出:
字典是键/值对的集合,可在其中提供键(或名称)来设置或检索相应的值:
@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)
此方法返回服务器上对应于指定虚拟路径的物理路径。 方法的三个参数是 virtualPath, baseVirtualDir和 allowCrossAppMapping。 (请注意,在声明中,参数以要接受的数据的数据类型列出。调用此方法时,必须提供所有三个参数的值。
将 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 语句
在代码中,你经常会遇到可能由于超出你控制的原因而失败的语句。 例如:
- 如果代码尝试打开、创建、读取或写入文件,则可能会出现各种错误。 所需的文件可能不存在,它可能被锁定,代码可能没有权限,等等。
- 同样,如果代码尝试更新数据库中的记录,则可能存在权限问题,可能会删除与数据库的连接,保存的数据可能无效,等等。
在编程术语中,这些情况称为 异常。 如果你的代码遇到异常,它会抛出一条错误信息,充其量也只是让用户感到恼火。
如果代码可能会遇到异常,并且为了避免出现此类型的错误消息,可以使用 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>