第1章 开发你的第一个ASP.NET应用——“Hello, World”

前面的预备课重点介绍了.NET Framework、ASP.NET与ASP.NET 4等一些重要的概念,并对Microsoft Visual Studio 2010集成开发环境做了概要性的阐述,从而使读者对Microsoft Visual Studio 2010与ASP.NET 4有了一定的认识和了解。

有这个良好的学习开端之后,我们将通过创建一个经典的“Hello, World”Web应用程序项目作为本章的切入点,来全面展示ASP.NET Web应用程序的开发步骤与项目的文件体系结构。除此之外,还将在本章重点阐述Web窗体的构成、ASP.NET网页代码模型、ASP.NET生命周期、配置文件和全局应用程序类的使用等相关的基础性内容,为后面章节的深入学习打下坚实的基础。

1.1 创建“Hello, World”Web应用程序

我们都知道,“Hello, World”程序是所有程序员一直以来的一个浪漫约定,也是一个伟大的梦想—总有一天,出自人类之手的计算机会面对这个美丽的世界说一声:“Hello, World”。当然,它也是学习任何一门新语言的一个很好的起点。我们就从这里开始,来看看利用ASP.NET如何创建美好的“Hello, World”程序。

1.1.1 创建解决方案和ASP.NET Web应用程序

在Visual Studio中,创建任何一个项目时,都得先创建一个解决方案。一个解决方案可以包含多个项目,而一个项目通常可以包含多个项,项可以是项目的文件和项目的其他部分,如引用、数据连接或文件夹等。解决方案和项目允许采用以下方式使用集成开发环境((IE):

❑作为一个整体管理解决方案的设置或管理各个项目的设置。

❑在集中精力处理组成开发工作的项的同时,用“解决方案资源管理器”处理文件管理细节。

❑添加对解决方案中的多个项目有用或者对该解决方案有用的项,而不必在每个项目中引用该项。

❑处理与解决方案或项目独立的杂项文件。

1.使用Visual Studio 2010创建一个项目解决方案

其实,在Visual Studio中创建解决方案非常简单,当使用Visual Studio创建一个新项目时,Visual Studio就会自动生成一个解决方案。然后,可以根据需要将其他项目添加到该解决方案中。“解决方案资源管理器”提供整个解决方案的图形视图,开发应用程序时,该视图可帮助你管理解决方案中的项目和文件。

Visual Studio将解决方案的定义分别存储在.sln文件和.suo文件中。其中,解决方案定义文件(.sln)存储定义解决方案的元数据,主要包括如下内容:

❑解决方案相关项目。

❑在解决方案级可用的、与具体项目不关联的项。

❑设置各种生成类型中应用的项目配置的解决方案生成配置。

我们只需要使用Visual Studio打开.sln文件就能够打开整个项目的解决方案,而.suo文件存储解决方案用户选项记录所有将与解决方案建立关联的选项,以便在每次打开时,它都包含你所做的自定义设置,例如你的Visual Studio布局或者你的项目最后编译的而又没有关掉的文件,等等。

注意.sln文件可以在开发小组的开发人员之间共享,而.suo文件是用户特定的文件,不能在开发人员之间共享。因此,.suo文件被系统隐藏了起来。

接下来,要向你推荐的是另外一种创建解决方案的方法,即创建不包含任何项目的空白解决方案。创建步骤如下:

1)依次选择“开始”→“程序”→“Microsoft Visual Studio 2010”→“Microsoft Visual Studio 2010”选项,进入Microsoft Visual Studio 2010集成开发环境。进入之后,将看见如图1-1所示画面。

figure_0041_0019

图 1-1 Microsoft Visual Studio 2010集成开发环境启动后的主窗体

2)在Microsoft Visual Studio 2010集成开发环境主窗体的工具栏中依次选择“File”→“New”→“Project”选项,在弹出的“New Project”窗体的“Installed Templates”列表中选择“Other Project Types”节点并展开,选中“Visual Studio Solutions”列表,并在模板列表中选择“Blank Solution”模板。在“Name”文本框中输入解决方案的名称(如“1-1”),在“Location”文本框中选择解决方案的存储路径,其他选项采用默认设置,单击“OK”按钮,如图1-2所示。

figure_0042_0020

图 1-2 添加解决方案

这样,一个空白的解决方案就创建了,如图1-3所示。该解决方案目前不包含任何项目和文件,可以说就是一个没有任何实际功能的空架子。

figure_0042_0021

图 1-3 解决方案窗体

2.在项目解决方案里面添加一个ASP.NET Web应用程序项目

上面已经创建了一个空白的解决方案,接下来的工作就是为这个空白解决方案添加一个ASP.NET Web应用程序项目。步骤如下:

1)在解决方案资源管理器里选中“1-1”解决方案,右击鼠标,在弹出的快捷菜单里选择“Add”→“New Project”命令,就会弹出如图1-4所示的“Add New Project”窗体。

figure_0043_0022

图 1-4 添加Empty ASP.NET Web Application

2)在“Add New Project”窗体的“Installed Templates”列表中选择“Visual C#”节点并展开,选中“Web”列表,并在模板列表中选择“Empty ASP.NET Web Application”模板,在“Name”文本框中输入ASP.NET Web应用程序项目的名称“HelloWorld”,在“Location”文本框中选择项目的存储路径,其他选项默认,单击“OK”按钮。这样,一个完整的ASP.NET Web应用程序项目便创建了,如图1-5所示。

figure_0043_0023

图 1-5 “Hello, World”Web应用程序项目

注意或许用心的你早已经发现,无论是在新建解决方案还是在新建项目的窗体顶部都有一个选择.NET Framework版本的下拉表,该下拉表默认选择.NET Framework 4版本。其实,早在Visual Studio 2008就提供了这样的功能,该功能提供了.NET Framework向下版本兼容的支持。也就是说,你可以根据自己的需要在Visual Studio 2010里开发基于.NET Framework 4、.NET Framework 3.5、.NET Framework 3.0、.NET Framework 2.0等相关版本的软件项目。

3.为什么要选择创建空白解决方案

其实,微软在Visual Studio 2010中提供了很多现成的解决方案来帮助项目开发人员降低开发的工作量,加快开发进度,如多项目解决方案、临时项目解决方案、独立项目解决方案等。但是在实际项目开发中,还是建议使用空白解决方案。下面就来看看采用空白解决方案会给我们带来哪些好处:

1)可以在空白解决方案中建立一个或者多个相关联的项目。我们知道,软件项目的规模有大小之分,在一些项目规模比较小而且功能又非常简单的项目中,通常的做法是一个解决方案对应一个项目;但如果在规模比较大、复杂度比较高的软件项目中,无论是从架构概念上讲,还是从软件项目本身的功能结构上讲,都需要把它拆分成多个小项目进行开发,以减少项目的复杂度。这时如果还使用一个解决方案对应一个项目,不论是开发调试的方便性,还是开发人员的协作开发都会受到影响。在这种情况下,比较好的做法是:创建一个空白解决方案,然后在该空白解决方案下创建多个相对应的子项目,这样就可以免除在多个解决方案之间不停转换、项目的调试困难等带来的麻烦。

2)可以在空白解决方案中建立多项目解决方案。在实际开发中,还会经常碰见这种情况,在一些规模比较小的软件公司,往往一个人要同时负责公司的多个软件项目的开发。为了能够减少开发人员在不同的解决方案之间来回转换所花费的时间与精力,可以将自己负责的多个项目纳入一个空白解决方案中,用解决方案文件夹来统一管理。

3)可以在空白解决方案中独立处理“杂项文件”文件夹中的文件,而不需要特定项目参与。杂项文件通常位于解决方案和开发项目的外部,相对独立,如一些程序的通用示例、开发说明、数据库架构等。在实际开发中,这些文件往往是开发人员所必需的,也是软件项目的后期维护与再开发必不可少的一部分。如果把这些文件分开存放,无疑是给开发和后期的维护增加麻烦。这时,可以使用空白解决方案来管理这些杂项文件,如打开阅读,甚至进行修改。也就是说,空白解决方案可以独立处理“杂项文件”文件夹中的文件,而不需要特定项目参与。

与普通程序文件不同的是,杂项文件夹中的杂项文件只表示为一个连接,就好像文件的快捷方式,不属于解决方案的一部分。当打开某个解决方案时,与这个解决方案相关的所有杂项文件(上次关闭解决方案时打开的部分或者全部杂项文件)也会重新打开。

4)可以在空白解决方案中独立处理“解决方案项”文件夹中的项,而不需要特定项目参与。在Visual Studio的解决方案资源管理器中有一个叫做“解决方案项”的文件夹。这个文件夹中的项与普通的项有所不同,普通的项往往位于解决方案内部,而位于这个文件夹中的项却都是独立于项目之外进行管理的,同时又与解决方案有所关联,在这个文件夹中的项叫做“解决方案项”。其实它的作用跟上面讲到的“杂项文件”非常类似。

如果将这些“解决方案项”加入空白解决方案中,可以实现如下两个功能:

❑可以独立地阅读、修改这些项目,而不需要打开特定的解决方案。

❑解决方案文件夹中的项可以在解决方案中编译和生成。虽然解决方案项独立于特定的解决方案,但是其毕竟是解决方案中的一个必不可少的功能。

总之,空白解决方案项对于管理单个解决方案的多个项目、杂项文件、解决方案项等提供了简便、独立的管理平台,因而可以在很大程度上降低开发人员的工作量,缩短项目开发的周期。

figure_0045_0024

图 1-6 创建ASP.NET Web应用程序项目的两种模板

4.ASP.NET Web Application与Empty ASP.NET Web Application

上面在创建ASP.NET Web应用程序项目时,我们选择了“Empty ASP.NET Web Application”模板进行创建。其实,还可以通过另外一种模板,即“ASP.NET Web Application”来创建,如图1-6所示。接下来,就来看看两者有什么区别。

1)Empty ASP. NET Web Application模板。从上面的例子中可以看出,使用Empty ASP.NET Web Application模板创建的项目是一个一个非常干净的项目,只拥有一个Web.config文件。它基本上就是一个空架子,没有任何可执行的文件,如图1-7所示。

2)ASP. NET Web Application模板。而ASP.NET Web Application模板正好与Empty ASP.NET Web Application模板相反,在选择ASP.NET Web Application模板创建ASP.NET Web应用程序项目时,你会发现所创建的ASP.NET Web应用程序项目在其中预先生成了一些目录和文件,如图1-8所示。

figure_0045_0025

图 1-7 Empty ASP.NET Web Application模板创建的ASP.NET Web应用程序项目

figure_0045_0026

图 1-8 ASP.NET Web Application模板创建的ASP.NET Web应用程序项目

它包含了一个Site.Master母版页文件,该文件提供了网站总的布局(含有页眉、页脚等),在Styles文件夹里使用了一个含有所有样式的CSS样式文件Site.css。在Scripts文件夹里面内含了jQuery文件((AP.NET AJAX可以通过脚本管理控件来提供)。在根目录中,它还包含了基于母版页的“Default.aspx”和“About.aspx”网页。除此之外,还在Account文件夹内包含并实现了基于表单的认证系统的若干网页,可用来登录、注册和改变用户的密码。在这里,你不用编写任何代码或配置文件就可以运行这个项目,得到一个运行正常的网站,如图1-9和图1-10所示。

1.1.2 创建“Hello, World”Web页面

上一小节通过Microsoft Visual Studio 2010集成开发环境创建了一个空白解决方案和一个空白的ASP.NET Web应用程序项目“HelloWorld”。搭好这些项目架子之后,下面就来给这个“HelloWorld”Web应用程序项目添加一些可执行的文件,让它为我们问候一声“Hello, World”。

figure_0046_0027

图 1-9 运行Default.aspx页面

figure_0046_0028

图 1-10 运行Account/Login.aspx页面

1.添加Login.aspx页面

首先,需要创建一个Login.aspx页面来作为本系统的入口。步骤如下:

1)用鼠标右击“HelloWorld”项目,在弹出的快捷菜单里选择“Add”→“New Item”选项,就会弹出一个Add New Item窗体,如图1-11所示。

figure_0046_0029

图 1-11 Add New Item窗体

2)展开左边的“Visual C#”列表并选中“Web”选项,这时中间的模板列表就会列出所有关于开发ASP.NET Web应用程序项目的模板页。在这里,因为我们开发的是一个登录页面,所以我们选择“Web From”模板页,并命名为“Login.aspx”,将名字填在Name文本框里,单击“Add”按钮,这样就为“HelloWorld”项目添加了一个登录页面Login.aspx,如图1-12所示。

figure_0046_0030

图 1-12 添加Login.aspx页面后的解决方案资源管理器

其实,一个完整的ASP.NET Web窗体由.aspx、.aspx.cs与.aspx.designer.cs三个文件组成,现在就以Login.aspx页面为例,大致了解一下它们各自的作用,以及它们之间是如何协作运行的。

1)Login. aspx文件。习惯上把它称为页面文件,它存储的是页面设计描述代码,即Web窗体的HTML代码,我们就是通过它来为用户提供友好的操作界面。打开Login.aspx文件,在代码编辑框内选择“Source”选项就能够看见Visual Studio编辑器已经为我们生成好的页面设计描述代码,如代码清单1-1所示。

代码清单1-1 Login.aspx


<%@Page Language="C#"AutoEventWireup="true"CodeBehind="Login.aspx.cs"

Inherits="HelloWorld.Login"%>

<!DOCTYPE html PUBLIC"-//W3C//DTD XHTML 1.0 Transitional//EN"

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

<title></title>

</head>

<body>

<form id="form1"runat="server">

<div>

</div>

</form>

</body>

</html>


在这个文件里,可以根据自己的设计要求添加或修改页面的样式、布局、页面控件等。

2)Login. aspx.cs文件。它是C#代码文件,主要存储的是C#代码,比如与数据库相关的查询、更新、删除操作,还有各个页面按钮的点击事件等,如代码清单1-2所示。

代码清单1-2 Login.aspx.cs


using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

namespace HelloWorld

{

public partial class Login:System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)

{

}

}

}


注意所有的Web窗体在新建时都会自动继承System.Web.UI.Page类。当然也可以让它继承自己的基类,如public partial class Login:MyPage。在这里,MyPage就是你自己的页面基类,基类也必须继承System.Web.UI.Page类。

3)Login. aspx.designer.cs文件。页面设计代码文件通常存储的是一些页面控件的配置信息,就是注册控件页面。这是页面设计器生成的代码文件,作用是对页面上的控件进行初始化,如代码清单1-3所示。

代码清单1-3 Login.aspx.designer.cs


namespace HelloWorld

{

public partial class Login

{

///<summary>

///form1 control.

///</summary>

///<remarks>

///Auto-generated field.

///To modify move field declaration from designer file to code-behind file.

///</remarks>

protected global:System.Web.UI.HtmlControls.HtmlForm form1;

}

}


如上所示,我们在Login.aspx文件中创建了一个form控件“<form id="form1"runat="server">”,这时就会在Login.aspx.designer.cs里生成相应的设计代码“protected global:System.Web.UI.HtmlControls.HtmlForm form1”,所以它必须和页面控件保持一致。

4)三者之间的联系。这时候,或许用心的你会问,它们三者之间是如何协同工作的呢?答案很简单,它们就是通过Login.aspx文件的“<%@Page Language="C#"AutoEventWireup="true"CodeBehind="Login.aspx.cs"Inherits="HelloWorld.Login"%>”语句将三者有效地联系起来的。其中,Language用于指定绑定代码的语言类型,CodeBehind用于指定绑定的.aspx.cs文件,Inherits用于指定绑定的.aspx.designer.cs文件。关于页面代码模型和“Page”指令的更多知识,将在后面的章节更详细的阐述。

经过上面的讲解,相信大家现在已经对ASP.NET Web窗体有了深入的了解和认识,下面就来继续完善Login.aspx文件的功能:

1)打开Login.aspx文件,为了能够直观地看见Web窗体的编辑效果,在代码编辑框内选择“Split”选项。同时,在“Toolbox”里展开“Standard”列表,这样就能够清楚地看见Visual Studio为窗体设计提供的标准服务器端控件。在“Standard”列表里选中“TextBox”控件,按住鼠标左键将其拖入Login.aspx页面中,在属性框里面将“TextBox”控件的“((I)”属性设置为“txt_UserName”,将“Width”属性设置为“166px”,如图1-13所示。

依照上面的方法,继续选择一个“Button”控件拖入Login.aspx页面中,在属性框里面将“Button”控件的“((I)”属性设置为“bt_Login”,将“Text”属性设置为“登录”。这样,一个简单的登录页面就算基本设计完成,如图1-14所示。

figure_0048_0031

图 1-13 “TextBox”控件的属性设置

在设计中,我们不难发现,每当向设计页面拖入一个控件的时候,Login.aspx页面的HTML代码文件就会做相应的改变。当设计完Login.aspx时,代码中便增加了如下两行代码:


<asp:TextBox ID="txt_UserName"runat="server"Width="166px"></asp:TextBox>

<asp:Button ID="bt_Login"runat="server"Text="登录"/>


因此,在Visual Studio中,不仅可以直接对控件使用“拖曳”的方式进行设计,还可以以修改页面的HTML代码的方式来达到设计的要求。

2)设计好Login.aspx页面之后,就需要编写相关代码来实现我们需要的功能了。

figure_0049_0032

图 1-14 Login.aspx页面设计

用鼠标双击Login.aspx页面的“登录”控件,为它添加一个事件bt_Login_Click,打开Login.aspx.cs文件,修改bt_Login_Click事件里面的代码,如代码清单1-4所示。

代码清单1-4 Login.aspx.cs


using System;

using System.Collections.Generic;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

namespace HelloWorld

{

public partial class Login:System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)

{

}

protected void bt_Login_Click(object sender, EventArgs e)

{

//将txt_UserName控件的内容存储到Session

if(this.txt_UserName.Text==String.Empty)

{

this.Session["UserName"]="World!";

}

else

{

this.Session["UserName"]=this.txt_UserName.Text.ToString();

}

//将页面转向到Default.aspx

Response.Redirect("Default.aspx");

}

}

}


2.添加Default.aspx页面

有上面的登录页面之后,还需要创建一个Default.aspx页面将系统所问候的信息给用户显示出来。步骤如下:

1)创建一个Default.aspx页面,并在Default.aspx页面里添加一个Label控件,该控件用于向我们显示友好的问候语,代码如下所示:


<asp:Label ID="lb_content"runat="server"></asp:Label>


2)创建好lb_content控件之后,接下来就是在Default.aspx.cs文件中编写代码让lb_content控件将友好的问候语显示出来,如代码清单1-5所示。

代码清单1-5 Default.aspx.cs


using System;

using System.Collections.Generic;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

namespace HelloWorld

{

public partial class Default:System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)

{

//将问候语赋给lb_content控件

this.lb_content.Text="Hello,"+Session["UserName"].ToString();

}

}

}


1.1.3 编译运行程序

到目前为止,“Hello, World”Web应用程序项目基本上创建完毕,余下的工作就是编译运行该项目了。

1.设置启动项目和项目起始页

当一个解决方案中存在多个Web应用程序项目时,就需要设置其中的一个Web应用程序项目为启动项目。设置方法:选择需要设置的Web应用程序项目,右击鼠标,在弹出的快捷菜单里选择“Set as StartUp Project”选项即可。

当一个启动项目中有多个Web页面的时候,就需要设置其中的一个页面为项目的起始页。设置方法:选择要设置的Web页面并右击鼠标,在弹出的快捷菜单里选择“Set as Start Page”命令。在本项目中,将Login.aspx设置为项目的起始页。值得注意的是,Visual Studio总是将Default.aspx默认为起始页,如果不设置,系统将默认为Default.aspx页面。

2.编译运行“Hello, World”

设置好项目的起始页之后,按“Ctrl+F5”键就可以开始运行该Web项目了。注意,按“Ctrl+F5”键只运行程序,而不执行调试操作。运行结果的界面如图1-15所示。

figure_0051_0033

图 1-15 Login.aspx页面

在图1-15中,如果在文本框里不输入任何名称,直接登录,那么Default.aspx页面将会输出“Hello, World”,如图1-16所示;如果在文本框里输入自己的名字,比如输入“马伟”,那么Default.aspx页面将会输出“Hello,马伟”,如图1-17所示。

figure_0051_0034

图 1-16 直接登录的Default.aspx页面

figure_0051_0035

图 1-17 输入名字后的Default.aspx页面

1.1.4 调试运行程序

通常,我们所编写的程序经常会在编译的时候出现一些错误或者异常而导致编译不成功;又或者是编译成功了,运行的结果却不是我们所期望的,等等。这时,就需要通过调试运行程序来查找错误的原因,而不能够采取直接运行程序的方法。

在调试Web应用程序方面,Visual Studio提供了很好的解决方案,它与调试一般的程序一样简单。当需要调试某个特定的网页时,只需要将其页面所在的项目设置为解决方案的启动项目,并将该页面设置为项目起始页,然后设置好断点,单击工具栏上的“Start Debugging”按钮或者使用快捷键“F5”就可以进行调试了。

需要注意的是,调试页面的运行还取决于项目所在的位置。如果你的项目保存在远程Web服务器或本地IIS的虚拟目录中,Visual Studio将直接启动你的默认浏览器并导航到合适的URL;如果没有为你的Web应用程序项目设置IIS,而使用文件系统应用程序((Vsual Studio默认的方式),Visual Studio将在一个动态随机选择的端口上启动它整合的Web服务器,然后运行默认浏览器并向它传递指向本地Web服务器的URL。在这两种方式下,编译页面并创建页面对象的工作都被交给了ASP.NET工作进程来管理。

注意 早在Visual Studio 2005的时候,就在Visual Studio开发环境中内建了Web服务器,它允许你不用为Web应用程序创建IIS就能够调试和运行Web应用程序项目,它只在Visual Studio运行时才运行,并且只接受来自你的计算机的请求。当Visual Studio启用一个集成的Web服务器时,将在系统托盘中添加一个图标,你可以通过双击该图标来获取关于内建Web服务器的更多信息,或者想关闭内建Web服务器。

在实际调试中,可以按照如下步骤进行:

1)设置调试断点。要想调试运行程序,首先就得设置一个断点以便于Visual Studio调试程序找到调试的入口。在这里,假设将Login.aspx.cs文件里的语句“if(this.txt_UserName.Text==String.Empty)”设置为调试断点。设置方法:单击代码旁的边界,会出现一个红色的圆点,同时该语句的背景色也会变成红色,这样就表示已经将该句设置成了调试断点,如图1-18所示。

figure_0052_0036

图 1-18 设置断点

注意 断点可以设置在任何可执行的代码行上,但不可以设置在变量声明、注释或空行上。

2)启动调试。设置好调试断点之后,就可以单击工具栏上的“Start Debugging”按钮或者使用快捷键“F5”启动调试页面。这时程序运行到断点处时执行就会中断,你将会被带回到Visual Studio的代码窗口,断点处的语句不会被执行,你现在可以使用快捷键调试你的Web项目程序,如表1-1所示。

3)查看调试结果。如图1-19所示,代码处于中断模式时,可以把鼠标停留在变量上查看它的当前内容,借此来验证变量是否包含预期的值。还可以在“Immediate Windows”命令窗口输入相关程序功能语句来查看相关结果。

figure_0052_0037

figure_0053_0038

图 1-19 调试窗口

4)结束调试。可以使用单击工具栏上的“Stop Debugging”按钮或者使用快捷键“Shift+F5”来停止程序的调试,最后别忘了取消调试断点。方法与设置调试断点一样。