⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 businessobjs.aspx

📁 书籍教程 >> .Net教程 >> asp.net编程精彩百例
💻 ASPX
字号:
<%@ Register TagPrefix="Acme" Namespace="Acme" Assembly="QSTools" %>
<%@ Register TagPrefix="Acme" TagName="SourceRef" Src="/quickstart/aspplus/util/SrcRef.ascx"%>

<!-- #include virtual="/quickstart/aspplus/include/header.inc" -->

<h4>处理业务对象</h4>
<p>

<div class="indent" style="font-family:Verdana; font-size:8pt;">
    <b> <img align="middle" src="/quickstart/images/bullet.gif">&nbsp;&nbsp;</b><a class="toc2" href="#bindir">应用程序 /Bin 目录</a><br>
    <b> <img align="middle" src="/quickstart/images/bullet.gif">&nbsp;&nbsp;</b><a class="toc2" href="#importing">导入业务对象</a><br>
    <b> <img align="middle" src="/quickstart/images/bullet.gif">&nbsp;&nbsp;</b><a class="toc2" href="#twotier">简单的两层 Web 窗体页</a><br>
    <b> <img align="middle" src="/quickstart/images/bullet.gif">&nbsp;&nbsp;</b><a class="toc2" href="#threetier">简单的三层 Web 窗体页</a><br>
    <b> <img align="middle" src="/quickstart/images/bullet.gif">&nbsp;&nbsp;</b><a class="toc2" href="#summary">本节小结</a><br>
</div>
<p>
<hr>

在业务组件中封装逻辑是实际应用程序的基本组成部分,不论是基于 Web 的应用程序还是任何其他应用程序。在 ASP.NET 中,业务对象是多层 Web 应用程序(如包含数据访问层或通用应用程序规则层的应用程序)的生成块。本节说明如何编写一些简单的组件并将它们包括在应用程序的 Web 窗体页中。
<p>

<!--BEGIN SECTION--> <a name="bindir"><span class="subhead">应用程序 /Bin 目录</span>
<p>
使用 Web 应用程序组件的 COM 模型时遇到的问题是,这些组件必须注册(通常是使用 regsvr32 工具)后才能在传统的 ASP 应用程序中使用。对这些类型的应用程序进行远程管理通常是不可能的,因为注册工具必须在服务器上以本地方式运行。更为棘手的是,这些组件经应用程序加载后便在磁盘上保持锁定状态,必须使整个 Web 服务器停止运行后才能替换或移除这些组件。
<p>
为尝试解决这些问题,ASP.NET 允许将组件放置在已知目录中并在运行时自动找到它们。该已知目录总是命名为 <b>/bin</b>,并紧位于应用程序根目录(一个由 Internet Information 服务 (IIS) 定义的虚拟目录)下。这样做的好处是组件无需注册便可在 ASP.NET 框架应用程序中使用&mdash;&mdash;只需将组件复制到 /bin 目录或执行 FTP 文件传输便可部署组件。
<p>
除提供零注册方法部署复杂组件外,ASP.NET 不要求这些组件在运行时在磁盘上保持锁定状态。ASP.NET 在后台复制 /bin 中的程序集并加载这些 shadow 副本。原始组件即使在 Web 服务器仍在运行时也可以替换,而对 /bin 目录的更改则由运行时自动获取。当检测到更改时,ASP.NET 允许完成当前执行的请求,并将所有新传入的请求定向到使用新组件的应用程序。


<!--BEGIN SECTION--> <br> <a name="importing"><br> <span class="subhead">导入业务对象</span>
<p>
从最基本的层面看,业务组件只是一个类,可以从导入它的 Web 窗体页为其创建实例。下面的示例定义一个简单的 HelloWorld 类。该类有一个公共构造函数(当初次创建该类的实例时执行此构造函数)、一个称为 FirstName 的 <b>String</b> 属性和一个通过 FirstName 属性值打印问候语的 SayHello 方法。
<p>

<p><Acme:TabControl runat="server">
<Tab Name="C#">
using System;
using System.Text;

namespace HelloWorld {
  public class HelloObj {
    private String _name;

    public HelloObj() {
        _name = null;

    }

    public String FirstName {
      get {
        return _name;
      }
      set {
        _name = value;
      }
    }

    public String SayHello() {
      StringBuilder sb = new StringBuilder("Hello ");
      if (_name != null)
         sb.Append(_name);
      else
         sb.Append("World");

      sb.Append("!");
      return sb.ToString();
    }
  }
}
</Tab>

<Tab Name="VB">
Imports System
Imports System.Text

Namespace HelloWorld
  Public Class HelloObj
    Private _name As String

    Public Sub New
      MyBase.New()
      _name = Nothing
    End Sub

    Public Property FirstName As String
      Get
        Return(_name)
      End get
      Set
        _name = value
       End Set
    End Property

    Public Function SayHello() As String
      Dim sb As New StringBuilder("Hello ")
      If (_name <> Nothing) Then
         sb.Append(_name)
      Else
         sb.Append("World")
      End If
      sb.Append("!")
      Return(sb.ToString())
    End Function
  End Class
End Namespace
</Tab>

<Tab Name="JScript">
import System;
import System.Text;

package HelloWorld {
  public class HelloObj {
    private var _name:String;

    public function HelloObj() {
        _name = null;

    }

    public function get FirstName() : String
    {
        return _name;
    }
    public function set FirstName(value:String) : void
    {
        _name = value;
    }

    public function SayHello() : String {
      sb:StringBuilder = new StringBuilder("Hello ");
      if (_name != null)
         sb.Append(_name);
      else
         sb.Append("World");

      sb.Append("!");
      return sb.ToString();
    }
  }
}
</Tab>

</Acme:TabControl><p>

<p>
若要编译该类,应从命令行运行 C# 编译器 (Csc.exe)。<b>/t</b> 选项通知编译器生成库 (DLL),<b>/out</b> 选项通知编译器将结果程序集放置到的位置。本例中,应用程序的 /bin 目录紧位于本教程的“aspplus”虚拟根目录下,并假设该命令从示例目录,即 ...\QuickStart\AspPlus\Samples\WebForms\Busobjs 运行。
<p>

<div class="code"><pre>
csc /t:library /out:..\..\..\..\bin\HelloObj.dll HelloObj.cs
</pre></div>

<p>对于 Visual Basic,等效编译命令是:<p>
<div class="code"><pre>
vbc /t:library /out:..\..\..\..\bin\HelloObjVB.dll HelloObj.vb
</pre></div>

<p>对于 JScript,等效编译命令是:<p>
<div class="code"><pre>
jsc /out:..\..\..\..\bin\HelloObjJS.dll HelloObj.js
</pre></div>

<p>
该组件现在可供应用程序中任何需要使用它的 Web 窗体页使用。下面的 HelloObj.aspx 示例阐释了此功能。
<p>

<Acme:LangSwitch runat="server">
  <CsTemplate>
<Acme:SourceRef
  RunSample="/quickstart/aspplus/samples/webforms/busobjs/CS/HelloObj.aspx"
  ViewSource="/quickstart/aspplus/samples/webforms/busobjs/HelloObj.src"
  Icon="/quickstart/aspplus/images/helloobj.gif"
  Caption="C# HelloObj.aspx"
  runat="server" />
  </CsTemplate>
  <VbTemplate>
<Acme:SourceRef
  RunSample="/quickstart/aspplus/samples/webforms/busobjs/VB/HelloObj.aspx"
  ViewSource="/quickstart/aspplus/samples/webforms/busobjs/HelloObj.src"
  Icon="/quickstart/aspplus/images/helloobj.gif"
  Caption="VB HelloObj.aspx"
  runat="server" />
  </VbTemplate>
  <JsTemplate>
<Acme:SourceRef
  RunSample="/quickstart/aspplus/samples/webforms/busobjs/JS/HelloObj.aspx"
  ViewSource="/quickstart/aspplus/samples/webforms/busobjs/HelloObj.src"
  Icon="/quickstart/aspplus/images/helloobj.gif"
  Caption="JScript HelloObj.aspx"
  runat="server" />
  </JsTemplate>
</Acme:LangSwitch>


<p>
注意位于页面顶部的 <b>Import</b> 指令,它指定要包含的命名空间。使用该指令包含命名空间后,便可从 Web 窗体页内部使用该类。由于程序集由 ASP.NET 运行时预加载,因此只需简单的命名空间导入便可使组件可用。以下代码是 <b>Import</b> 指令的示例。
<p>

<div class="code"><pre>
&lt;%@ Import Namespace="HelloWorld" %&gt;
</pre></div>

<p>
默认情况下,ASP.NET 在应用程序启动时从 /bin 目录加载所有程序集。要加载的程序集通过配置系统指定。有关详细信息,请参阅<a href="configoverview.aspx">配置概述</a>一节。通过使用配置还可将附加的程序集导入应用程序。例如:
<p>

<div class="code"><pre>
&lt;configuration&gt;
    &lt;compilation&gt;
        &lt;assemblies&gt;
            &lt;!--The following assemblies are loaded explicitly from the global cache--&gt;
            &lt;add assembly="System.Data"/&gt;
            &lt;add assembly="System.Web.Services"/&gt;
            &lt;add assembly="System.Drawing"/&gt;
            &lt;!--This tells ASP.NET to load all assemblies from /bin--&gt;
            &lt;add assembly="*"/&gt;
        &lt;/assemblies&gt;
    &lt;/compilation&gt;
&lt;/configuration&gt;
</pre></div>

<b>注意:</b>从 /bin 加载的每个程序集被限制在它运行的应用程序的范围内。这意味着对等应用程序可以潜在地使用具有同一类名或命名空间名称的不同程序集,不会发生冲突。

<!--BEGIN SECTION--> <br> <a name="twotier"><br> <span class="subhead">简单的两层 Web 窗体页</span>
<p>

外部组件的典型用途是执行数据访问。它简化了页中的代码,增强了可读性并将用户界面 (UI) 逻辑与系统功能分开。下面的实例阐释了简单的两层 Web 窗体页,它使用数据访问组件检索产品信息。
<p>

<Acme:LangSwitch runat="server">
  <CsTemplate>
<Acme:SourceRef
  RunSample="/quickstart/aspplus/samples/webforms/busobjs/CS/TwoTier.aspx"
  ViewSource="/quickstart/aspplus/samples/webforms/busobjs/TwoTier.src"
  Icon="/quickstart/aspplus/images/twotier.gif"
  Caption="C# TwoTier.aspx"
  runat="server" />
  </CsTemplate>
  <VbTemplate>
<Acme:SourceRef
  RunSample="/quickstart/aspplus/samples/webforms/busobjs/VB/TwoTier.aspx"
  ViewSource="/quickstart/aspplus/samples/webforms/busobjs/TwoTier.src"
  Icon="/quickstart/aspplus/images/twotier.gif"
  Caption="VB TwoTier.aspx"
  runat="server" />
  </VbTemplate>
  <JsTemplate>
<Acme:SourceRef
  RunSample="/quickstart/aspplus/samples/webforms/busobjs/JS/TwoTier.aspx"
  ViewSource="/quickstart/aspplus/samples/webforms/busobjs/TwoTier.src"
  Icon="/quickstart/aspplus/images/twotier.gif"
  Caption="JScript TwoTier.aspx"
  runat="server" />
  </JsTemplate>
</Acme:LangSwitch>

<p>
数据访问组件采用其构造函数的单个参数来指定产品数据库的连接字符串。Web 窗体页调用该组件的 <b>GetCategories</b> 方法填充下拉列表,调用该组件的 <b>GetProductsForCategory</b> 方法显示用户所选类别的产品。

<!--BEGIN SECTION--> <br> <a name="threetier"><br> <span class="subhead">简单的三层 Web 窗体页</span>
<p>
三层应用程序模型扩展了两层方案,在 UI 和数据访问逻辑之间包含了业务规则。此模型允许 UI 开发人员处理更高抽象化的级别,而不是通过低级数据访问组件 API 直接操作数据。中间业务组件通常强制业务规则并确保遵守数据库的关系和主键约束。下面的示例使用中间组件基于客户端输入的两位供应商 ID 计算折扣。

<p>

<Acme:LangSwitch runat="server">
  <CsTemplate>
<Acme:SourceRef
  RunSample="/quickstart/aspplus/samples/webforms/busobjs/CS/ThreeTier.aspx"
  ViewSource="/quickstart/aspplus/samples/webforms/busobjs/ThreeTier.src"
  Icon="/quickstart/aspplus/images/threetier.gif"
  Caption="C# ThreeTier.aspx"
  runat="server" />
  </CsTemplate>
  <VbTemplate>
<Acme:SourceRef
  RunSample="/quickstart/aspplus/samples/webforms/busobjs/VB/ThreeTier.aspx"
  ViewSource="/quickstart/aspplus/samples/webforms/busobjs/ThreeTier.src"
  Icon="/quickstart/aspplus/images/threetier.gif"
  Caption="VB ThreeTier.aspx"
  runat="server" />
  </VbTemplate>
  <JsTemplate>
<Acme:SourceRef
  RunSample="/quickstart/aspplus/samples/webforms/busobjs/JS/ThreeTier.aspx"
  ViewSource="/quickstart/aspplus/samples/webforms/busobjs/ThreeTier.src"
  Icon="/quickstart/aspplus/images/threetier.gif"
  Caption="JScript ThreeTier.aspx"
  runat="server" />
  </JsTemplate>
</Acme:LangSwitch>


<!--BEGIN SECTION--> <a name="endofsection">

<h4><a name="summary">本节小结</a></h4>
<ol>
<li>ASP.NET 运行时在已知的 /bin 目录(紧位于应用程序的根目录下)中查找业务对象(本地程序集)。/bin 目录具有以下优点: <p>
<ul>
<li><b>不需要注册。</b>不需要任何注册便可使程序集供应用程序中的页使用。程序集因其位于 /bin 目录中而可用。只需复制或 FTP 到此位置便可对编译代码进行部署。
<li><b>不需要服务器重新启动。</b>当 ASP.NET 框架应用程序的任何部分发生更改(例如,当 /bin 中的 DLL 被替换时)时,将立即针对更改的文件开始执行新请求。当前执行的请求可以在原来的应用程序移除前完成。当更改应用程序,甚至是替换编译代码时,Web 服务器也不需要重新启动。
<li><b>没有命名空间冲突。</b>从 /bin 加载的每个程序集被限制在它正在运行的应用程序的范围内。这意味着对等应用程序可以潜在地使用具有同一类名或命名空间名称的不同程序集,不会发生冲突。
</ul>
<p>
<li>程序集中的类可通过 .aspx 文件中的 <b>Import</b> 指令由应用程序中的页使用。
<li>两层应用程序简化了页中的代码,增强了可读性并将用户界面 (UI) 逻辑与系统功能分开。
<li>三层应用程序扩展了两层模型,使 UI 开发人员能够处理更高级的抽象化。中间业务组件通常强制业务规则并确保遵守数据库的关系和主键约束。
</ol>
<p>

<!-- #include virtual="/quickstart/aspplus/include/footer.inc" -->

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -