C#开发训练营

第1课:ASP.NET(1)——Web项目基础

本教程示例主要围绕一个ASP.NET Web项目展开,我们首先回顾ASP.NET Web项目开发的基础内容。如果读者需要了解更多关于Web开发的内容,可以参考作者的《网站全栈开发指南:HTML+CSS+JavaScript+ASP.NET》一书。本课将讨论ASP.NET Web项目中的一些常用文件类型和目录。

Web窗体

除了静态的HTML文本,Web窗体是ASP.NET Web项目中的主要文本类型之一,用于构建在服务器端可编程的动态页面。

Web窗体文件主要包括两类代码,一是传统的HTML、CSS和JavaScript代码(以下简称HTML部分);第二是在服务端执行的代码,包括服务器端定义指令、Web控件和逻辑代码等(以下简称C#代码部分)。

Web窗体页面的主文件扩展名为.aspx,如网站的默认页面Default.aspx。对于简单的页面,HTML内容和C#代码等内容可以放在一个文件,在创建Web窗体文件时,不选择“将代码放在单独的文件中”项,如图1。

图1

这里创建的TestPage.aspx页面位于网站根目录下,默认代码如下。

HTML
<%@ Page Language="C#" %>

<!DOCTYPE html>

<script runat="server">

</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
        </div>
    </form>
</body>
</html>

代码中的第一行是页面的Page指令,这里定义了一个参数Language,指定动态代码的编程语言,本书示例中使用的是C#编程语言,此外,也可以使用VB等编程语言。

<!DOCTYPE html>是HTML5页面的标准定义。

接下来的script元素中使用了runat属性,并指定属性值为server,说明这一部分的代码是在服务器端执行的。请注意区分,不包含runat属性的script元素用于引用JavaScript文件或定义JavaScript代码。

页面元素中的runat属性,目前只支持server属性值,表示元素在服务器端处理。

接下来是比较标准的HTML页面内容,需要注意的是head和form元素都使用了runat="server"属性,说明这两个元素都是可以在服务器端处理的。

接下来,我们在form元素中添加一些新的元素,如下面的代码。

HTML
<form id="form1" runat="server">
<p>
<label>打开时间</label>
<asp:Label ID="lbl1" runat="server" />
</p>
<p>
<label>回调时间</label>
<asp:Label ID="lbl2" runat="server" />
</p>
<p>
<asp:Button ID="btn1" Text="回调操作" runat="server" />
</p>
</form>

代码中添加了一些HTML元素,其中的三个Web控件分别是两Label控件,使用asp:Label元素定义,一个Button控件,使用asp:Button元素定义。接下来,在<script runat="server">和</script>之间添加一些代码,用于服务器端的处理,如下面的代码。

C#
<script runat="server">
    protected void Page_Load(object sender, EventArgs e)
    {
        if (IsPostBack == false)
        {
            lbl1.Text = DateTime.Now.ToString();
        }
        else
        {
            lbl2.Text = DateTime.Now.ToString();
        }
    }
</script>

首次打开页面时效果如图2,此时,lbl1会显示页面打开时的系统时间,lbl2没有显示内容。

图2

接下来,每一次点击“回调操作”按钮(btn1)时,lbl2就会显示回调的时间,但lbl1中的页面打开时间是不会变化的。

本例中操作的关键就是页面的IsPostBack属性,它表示页面是否为回调操作,当页面第一次打开时,属性值为false,此时可以进行一些页面的初始化操作;当通过按钮或其它控件进行回调操作后,IsPostBack属性值就变为true,此时可以对客户端提交的数据进行相应的处理。

项目开发过程中,一般会将HTML部分和C#代码分别放在不同的文件中,此时,HTML部分定义在.aspx文件,如Test.aspx文件;页面的C#代码部分定义在对应的.aspx.cs文件中,如Test.aspx.cs文件。此时,由于.aspx页面中不再定义C#代码,所以就不再需要包含runat="server"属性的script元素。

创建Test.aspx页面时可以参数如图3中的设置,这里应选中“将代码放在单独的文件中”。

图3

下面的代码是Test.aspx文件中的Page指令部分。

ASP.NET
<%@ Page Language="C#" AutoEventWireup="true" 
    CodeFile="Test.aspx.cs" Inherits="Test" %>

除了Language属性,这里还多了三个属性,分别是:

  • AutoEventWireup,指定是否自动关联事件处理代码,这里定义为true。
  • CodeFile,指定页面对应的代码文件,这里指定为Test.aspx.cs。
  • Inherits,指定继承的类,这里指定为Test。

那么,Test类定义什么地方呢?我们来看Test.aspx.cs文件的默认内容,如下面的代码。

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class Test : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }
}

可以看到,Test.aspx.cs文件中的主体内容就定义Test类,它继承于System.Web.UI.Page类,大家可以在帮助文档中查阅Page类的完整定义,开发过程中常用的属性有:

  • IsPostBack,刚才已经看到些属性的应用,它表示页面是否为回调状态。
  • Title,页面的标题,客户端最终会呈现在title元素中,会显示在浏览器的标题栏或标签中。
  • Controls属性,页面中Web控件的集合,包括使用asp:前缀定义的Web控件或自定义控件,并且控件中包括了runat="server"属性。

此外,在Page类中还定义了当前上下文(Context)关联的Request、Response、Server和Session对象属性,后续课程会看到具体的应用。

Web.config配置文件

Web.config文件是网站的配置文件,定义在网站的根目录下,下面的代码是源代码中使用的部分配置内容。

XML
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0"></compilation>
    <httpRuntime maxRequestLength="102400" executionTimeout="600" 
                 requestValidationMode="2.0" />
    <pages>
      <controls>
        <add tagPrefix="acl" 
            tagName="PageHeader" src="/lib/ctr/PageHeader.ascx" />
        <add tagPrefix="acl" 
            tagName="PageFooter" src="/lib/ctr/PageFooter.ascx" />
      </controls>
    </pages>
  </system.web>
</configuration>

Web.config文件使用了XML格式定义,下面是些常用的参数设置。

compilation节点中,debug属性设置是否开启调试模式,在开发过程中设置为true可以帮助开发者跟踪执行错误;targetFramework设置.NET Framework平台版本,源代码中设置为4.0。修改ASP.NET Web项目.NET Framework平台的版本时,可以在“解决方案资源管理器”中的项目右键菜单“属性页”打开项目属性窗口,在“生成”页中的“目标框架”项设置所需要的版本,如图4。

图4

httpRuntime节点设置设置一些运行时参数,其中,maxRequestLength设置可以上传的数据尺寸,单位为KB,默认值为4096,即4MB,这里设置设置为100MB,开发中可以根据应用中上传文件的实际需求设置。executionTimeout参数设置服务器执行的超时时间,单位为秒。requestValidationMode设置请求验证模式,如果页面中需要提交HTML内容,可以设置为2.0,并在页面的Page指令中设置ValidateRequest属性为false,在读取Word文档内容和文章发布相关内容时会使用这些设置。

controls节点中使用add节点添加了两个自定义控件,其中,tagPrefix属性设置控件定义时的前缀,tagName属性设置控件的名称,src属性设置自定义控件的文件路径,如本例中的自定义控件文件就是位于网站/lib/ctr目录下的.ascx文件,和.aspx页面相似,自定义控件的HTML内容定义在.ascx文件中,而相关的C#代码一般定义在对应的.ascx.cs文件中,后续课程会有自定义控件的讨论,这里,如果还没有创建自定义控件,也可以将控件注册内容删除。

Global.asax文件

Global.asax称为全局应用程序类文件,同样定义在网站根目录下;下面的代码就是源代码中使用的Global.asax文件内容。

C#
<%@ Application Language="C#" %>

<script runat="server">
    void Application_Start(object sender, EventArgs e) 
    {
        // 在应用程序启动时运行的代码
        tApp.Init();
    }
    
    void Application_End(object sender, EventArgs e) 
    {
        //  在应用程序关闭时运行的代码

    }
        
    void Application_Error(object sender, EventArgs e) 
    { 
        // 在出现未处理的错误时运行的代码

    }

    void Session_Start(object sender, EventArgs e) 
    {
        // 在新会话启动时运行的代码
        // Response.Redirect("/");
    }

    void Session_End(object sender, EventArgs e) 
    {
        // 在会话结束时运行的代码。 
        // 注意: 只有在 Web.config 文件中的 sessionstate 模式设置为
        // InProc 时,才会引发 Session_End 事件。
        // 如果会话模式设置为 StateServer
        // 或 SQLServer,则不引发该事件。
    }
</script>

代码中定义了五个方法,分别应对ASP.NET Web应用执行期间的三个事件,以及用户连接会话处理的的两个事件。

其中,应用事件响应方法包括:

  • Application_Start()方法,处理ASP.NET Web应用启动时的代码,这里可以进行一些应用的初始化工作,如代码中调用了tApp类的Init()方法进行初始化工作,代码定义在/app_data/app/tApp.cs文件。
  • Application_End()方法,处理ASP.NET Web应用结束时的代码。
  • Application_Error()方法,当应用中出现了没有处理的错误时会调用此方法,Web应用发布后,如果不想让用户看到没有处理的错误信息,将代码中的Response.Redirect("/")变为正式代码,这样,当出现没有处理的错误时就会跳转到网站主页,如果项目中设置了统一的错误提示或帮助页面,也可以在此跳转到到指定的处理页面。

会话(Session)相关的响应方法包括:

  • Session_Start()方法,当有新的用户连接时执行此方法。
  • Session_End()方法,当会话连接结束时执行此方法。请注意,在默认的代码中也有提示,只有采用InProc方式处理会话时才会执行此方法。ASP.NET Web项目中,InProc也是默认的会话处理方式。

bin目录

ASP.NET Web项目中,根目录下的bin目录用于保存已编译的库文件(*.dll),在发布的网站中,bin目录中存放了所有类的编译结果;而在开发过程中,bin只保存引用的库文件,如支持MySQL数据库的MySql.Data.dll文件等。

app_code目录

开发过程中,网站根目录下的app_code目录用于存放项目中的源代码文件,这里可以使用C#代码(.cs),也可以使用VB.NET(.vb)等代码;甚至可以在同一项目中使用不同语言的代码,只需要合理地组织它们就行。运行网站时,app_code目录中的代码都会自动编译。

app_data目录

根目录下的app_data目录中的文件不能使用URL直接访问,这样就保证了文件的安全性,可以将SQLite数据库、Access数据库、需要访问控制的文件放在此目录。代码中,可以使用Server.MapPath()方法获取文件的实际路径。