一、Geting Started
。高性能,ASP+被编译成NGWS运行时代码,早帮定,JIT编译,缓存技术
。开发工具支持,WYSIWYG的编辑环境
。强大而灵活,基于NGWS运行时环境,丰富的支持库,消息机制,数据访问,语言
无关,同时兼容现有的COM体系
。简单,部署和培植,表现层和逻辑层分离,自动垃圾回收
。管理方便,文本文件做配置,实现“0管理”,甚至可以覆盖正在运行的已编译
的代码。
。伸缩性好,可用性高,集群,多处理器
。可定制,扩展性好,可任意子类化已经有的类,实现定制的用户人证和状态服务
。安全,与系统集成,基于应用的安全保证
语言支持,ASP+已经内置三中,C#,VB,JSCRIPT
例:
属性定义:
public String name{ get { ..... return ...; } set { ...= value; } }
事件处理:
void MyButton_Click(Object sender,EventArgs e)
{
...
}
造型(即强制类型转换,但与之梢不同,参见JAVA):
MyObject obj = (MyObject)Session["somevalue"];
IMyObject iobj=obj;
名称空间:
using System;
Main方法:
public static void Main(String[] args)
注意,C#中的args跟java一样,不包含执行文件自己。
二、Asp+ Web Forms
1).介绍
ASP+ WEB FORMS是在服务器端的用以动态生成WEB页面的编程模型,基于NGWS运行
时环境之上。
。重用UI控件,减少编程量
。清晰的页面逻辑
。强大的编辑工具
ASP+ WEB FORMS是以.aspx为后缀的文件,被编译成NGWS的类,只需一次编译。
法一、将一个普通的HTML文件后缀改成.aspx
法二、使用<% %>代码块
但以上不是推荐作法,不利于逻辑和表现分离。
。ASP+服务器控件
在aspx文件中,包含属性runat=server的标记
服务器控件在运行时产生HTML代码。
服务器控件自动维护了客户端的输入,程序不用去处理客户输入,也不用在客户
端写脚本(注意,服务器并没有把数据保存在服务器上,而是通过一个hidden
域来工作的)。
。处理服务器控件的事件
呀,注意,这些事件其实是在客户端发生的呢,但你不用管,就当在为一个VB的
FORM中的控件写事件处理程序。
。使用定制的服务器控件
ASP+自带45个内置的服务器控件,也可以自己写
。数据帮定
内置了DataGrid等控件,他们支持模板
。FORM验证控件
内致了许多Validator,可以强制必须为某一个字段输入内容等。
。代码隐藏
可进一不实现代码与表现分离
2).使用服务器控件
runat=server
可以有属性
可以有事件
<asp:hyperlink runat="server">实现页面导航
Page.Navigate(url)也可以实现页面导航
3).为服务器控件增加风格(CSS)
可以像CSS那样去控制,还可以用Style对象,例:
Style style=new Style(); Style.BorderColor = Color.Black; ... MyLogin.ApplyStyle(style);
4).表单验证
验证控件只对部分控件有效,他们是:
HtmlInputText value HtmlTextArea value HtmlSelect value HtmlInputFile value TextBox Text ListBox SelectedItem DropDownList SelectedItem RadioButtonList SelectedItem 验证控件有如下几种: RequiredFieldValidator,必须填内容 CompareValidator,同某个常量或另外的控件的值做比较 RangeValidator,范围验证 RegularExpressionValidator,同一个模式做比较,用于EMAIL,邮政编码等验证 CustomValidator,自定义条件验证 ValidationSummary,显示验证后的错误信息摘要
如果客户端支持DHTML,验证控件将自动产生客户端验证脚本,否则,等提交回
服务器后在服务器端进行严整。
Page对象有个IsValid属性,如果验证失败,则被设为False,同时,页面中的
ValidationSummary控件(如果有的话)自动显示出错误信息。
。CompareValidator
该控件三个属性,ControlToValidate,ControlToCompare,Operator,分别代表要
验证的控件,比较的值,和比较方法。
。RangeValidator
三个属性:ControlToValidate,MiniumControl,MaxiumControl
。Regular
两个关键属性:ControlToValidate,ValidationExpression
例:
<asp:RegularExpressionValidator id="Regular1" runat="Server" ControlToValidate="TextBox1" ValidationExpression="^\d{5}$" Display="static" Font-Size="10pt">
邮政编码必须是5个数字
</asp:RegularExpressionValidator>
。自定义验证
需要自定义一个函数,如果放在客户端,则函数必须用ClientValidationFunction
属性指定,函数有格式:
function myvalidator(source,value)
source是CustomValidator对象。
如果在服务器端,则严整写在事件处理函数中:OnServerValidationFunction
例:
<script language="c#" runat="server"> bool ServerValidate(Object source,String value){ ... } </script> <asp:CustomValidator id="CustomValidate" runat="Server" ControlToValidate="Text1" OnServerValidationFunction="ServerValidate" ClientValidationFunction="ClientValidate"> 不是一个偶数哦! </asp:CustomValidator> <Script language="javascript"> function ClientValidate(source,value) { ,,,, } </Script>
5).Pagelet控件
自己做控件最简单的方法就是Pagelet控件,后缀为.aspc,用Register指令包含到WebForm中:
<%@ Register TagPrefix="Acme" TagName="Message" Src="pagelet1.aspc" %>
TagPrefix是Pagelet的名称空间定义,TagName是给Pagelet取的名字。Src属性是虚拟目录。
Pagelet的使用:
<Acme:Message runat="Server"/>
。暴露Pagelet的方法,像一个类一样定义属性,例:
<script language="c#" runat="server"> public String Address{ get{ return TxtAddress.Value; } set{ TxtAddress.Value=value; } } </script> <input id="TxtAddress" runat="server">
。封装事件
略
可以看出,Pagelet可以取代include文件的作用。
。编程创建Pagelet对象
可以用程序生成Pagelet控件的实例,如:
Control cl=LoadControl("pagelet2.aspc"); ((Pagelet2_aspc)cl).Category="business"; Page.Controls.Add(cl);
注意,因为LoadControl函数返回一个System.Web.UI.Control对象,因此需要造型。Pagelet
的类型为文件名,点号换成下划线。
6).数据帮定控件
asp+中,不仅可以帮定到数据库,还可以帮定到简单的属性集合,甚至方法调用的结果,如:
CustomerID: <%# custID %> <asp:ListBox id="List1" datasource='<%# myArray %>' runat="server"> <%# (Customer.FirstName + Customer.LastName)%> <%# GetBalance(CustID) %>
看起来跟asp中的<%=%>一样,但是ASP是用Response.Write来替换的,而ASP+则是在DataBind()
方法调用后才帮定的。数据帮定控件和Page对象都有DataBind()方法。
注意,asp+是强类型的,所以:
<%# count.ToString() %>才对。
。DataBinder.Eval()
一个静态方法,由ASP+支持,允许后帮定的数据帮定表达式,而且还可选地转化为串,可以
用于模板。如不用Eval,则像:
<%# String.Format("{0:c}",((DataRowView)Container.DataItem)["SomeInteger"]) %> 可以用Eval: <%# DataBinder.Eval(Container.DataItem,"someinteger","{0:c}") %>
7).服务器方数据访问
。连接、命令和数据集(DataSets)
NGWS提供了一系列受管数据访问API,引入名称空间:
<%@ Import Namespace="System.Data" %> <%@ Import Namespace="System.Data.SQL" %>
a).生成SQLConnection
b).构造SQLDatasetCommand
c).FillDataSet
如果是插入等操作,则用SQLCommand替换SQLDataSetCommand.
记住:始终在用完连接后关闭连接!否则要等到页面被释放时才会被垃圾回收机制释放资源。
。帮定数据到DataGrid,例:
....
DataSet ds = new DataSet(); myCommand.FillDataSet(ds,"Authors"); MyDataGrid.DataSource = ds.Tables["Authors"].DefaultView; MyDataGrid.DataBind();
。参数化查询
SQLDataSetCommand支持参数,"@"作为参数前缀,例:
myCommand.SelectCommand.Parameters.Add(new SQLParameter("@state",SQLDataType.VarChar,2)); myCommand.SelectCommand.Parameters["@state"].Value=newValue;
注意,如果DataGrid要在客户与服务器间轮转的话,一定要把MaintainState属性设置为false,
否则,性能受到影响,如:
<asp:DataGrid id="myDataGrid" runat="server"
MaintainState="false"/>
。插入数据
应当保证不为null,可以使用try/catch块。
例:
String insertcmd = "insert into Authors values(@id,@lname)" SQLCommand myc = new SQLCommand(insertcmd,myConn); myc.Parameters["@id"].Value=cu_id.Value; myc.Parameters["@lname"].Value=au_lname.Value; myc.ActiveConnection.Open(); try{ myc.Execute(); }catch(SQLException e){ if (e.Number==2627) ......//主键重复 } myc.ActiveConnection.Close();
。更新记录
DataGrid提供了一些内在支持,有一个整型属性,EditItemIndex,表示哪一行可以编辑,一但设置,
该行的文本输入框显示,而不是却省的静态文本,如为-1则表示没有行可以编辑。
DataGrid可以包含一个控件,EditCommandColumn,它将为DataGrid引发三个事件,EditCommand,
UpdateCommand,和CancelCommand。EditCommandColumn在属性中用Columns定义,如:
<ASP:DataGrid id="MyDataGrid" runat="server" ...... onEditCommand="MyDataGrid_Edit" onCancelCommand="MyDataGrid_Cancel" onUpdateCommand="MyDataGrid_Update" DataKeyField="au_id" > <property name="Columns"> <asp:EditCommandColumns EditText="编辑" CancelText="取消" UpdateText="更新"/> </property> </ASP:DataGrid>
Edit事件中参数DataGridCommandEventArgs参数包含了用户选择的行,然后我们可以重新帮定,
以刷新显示。例:
public void MyDataGrid_Edit(Object sender,DataGridCommandEventArgs E){ MyDataGrid.EditItemIndex = (int)E.Item.ItemIndex; BindGrid();//调用另外的函数实现重新帮定 }
在Cancel事件中,我们只需要把EditItemIndex设为-1就可以了。
在Update事件中,我们需要更新数据。要知道当前行的主键值,这可以用刚才设的DataKeyField
来获得,我们可以获得行的主键值,如:
myCommand.Parameters["@id"].Value=MyDataGrid.DataKeys[(int)E.Item.ItemIndex];
最后将EditItemIndex设为-1。
为了防止用户修改主键,可以单独定义一行中各列的表现,将其改为只读,如:
<ASP:DataGrid id="MyDataGrid" runat="server" ...... DataKeyField="au_id" AutoGenerateColumns="false" > <property name="Columns"> <asp:EditCommandColumn EditText="编辑" CancleText="取消" UpdateText="更新"/> <asp:BoundColumn HeaderText="au_id" SortField="au_id" ReadOnly="True" DataField="au_id"/> <asp:BoundColumn HeaderText="电话" SortField="phone" DataField="phone"/> ...... </property> </ASP:DataGrid>
。删除记录
加一个ButtonColumn控件,Command设为"Delete",将引发DeleteCommand事件。
。排序
当用户点一列的Header时,如果DataGrid的AllowSorting属性为True,则一个OnSortCommand
事件产生,参数DataGridSortCommandEventArgs的SortField传回来的是哪一个列被选中,如:
protected void MyDataGrid_Sort(Object src,DataGridSortCommandEventArgs E){ DataView source=ds.Tables["Authors"].DefautlView; Source.Sort=E.SortField; MyDataGrid.DataBind(); }
。表间关系
用一列做个连接,跳转到另一页去查看对应的详细资料,用控件HyperLinkColumn,如:
<property name="Columns"> <asp:HyperLinkColunn DataNavigateUrlField="au_id" DataNavigateUrlFormatString="a.aspx?id={0}" Text="详细情况" /> </property>
。访问基于xml的数据
DataSet有一个方法叫ReadXml,用FileStream作为参数,xml文件的格式为:
<DocumentElement> <TableName> <ColumnName1>Comumn Value</ColunName1> ...... </TableName> </DocumentElement>
每一个<TableName>段代表一行数据。
例:
DataSet ds = new DataSet(); FileStream fs = new FileStream(Server.Mappath("a.xml"),FileMode.Open,FileAccess.Read); StreamReader reader = new StreamReader(fs); ds.ReadXml(reader); DataView source = new DataView(ds.Tables[0]); MySpan.InnerHtml = source.Table.TableName; MyDataGrid.DataSource = source; MyDataGrid.DataBind();
还可以分别调用ReadXmlSchema和ReadXmlData分开读取模式和数据。
8).数据访问的定制
除了DataGrid之外,还有DataList和Repeater,可以更加灵活使用,不过你需要提供模板,
用控件templates
他们也有属性DataSource,可以赋予一个ICollection对象,ItemTemplate控件指定每一个记录
显示的样子,例:
<ASP:Repeater id="MyRepeater" runat="server"> <template name="itemtemplate"> <%# DataBinder.Eval(Container.DataItem,"name")%> </template> </ASP:Repeater>
其中:Container表示控件之外的第一个含System.Web.UI.INamingContainer的控件,本例中
是一个System.Web.UI.WebControls,RepeaterItem,包含了一个DataItem的属性。
另外,还可以使用HeaderTemplate和FooterTemplate。
DataList有更强的控制能力,比如他的RepeaterCoumns属性可指定一行重复几次,RepeatDirection
指定方向。
插入LinkButton控件可以引起select事件,DataList中可设OnSelectedIndexChanged属性指定事件Handler.
例:
<asp:DataList id="dl" OnSelectedIndexChanged="dl_Select"> <asp:LinkButton Command="select" runat="server"> <%#DataBinder.Eval(Container.DataItem."title")%> </asp:LinkButton> ...... <script language="c#" runat="server"> void dl_Select(Object sencer,EventArgs E){ ...... } </script>
注意,可能有多个事件,比如Edit/Update/Cancel,所以可以用一个统一的OnItemCommand来处理,
凭Command判断到底是什么事件。例:
void dl_select(Object src,DataListCommandEventArgs E){ String command=((LinkButton)E.CommandSource).Text; switch(command) {case "discuss":.....break; case "ratings":......break; } } <asp:LinkButton Command="ratings" runat="server"> View ratings </asp:LinkButton>
更妙的是,DataList还可以支持Edit和Select模板!!
例:
void MyDataList_Edit(Object sender,DataListCommandEventArgs E){ MydataList.EditItemIndex = (int)E.Item,ItemIndex; //设定谁被选中进行编辑 ......//重新帮定 } void MyDataList_Update(Object sender,DataListCommandEventArgs E){ String price = ((HtmlInputText)E.Item.FindControl("edit_price")).Value; ...... MyDataList.EditItemIndex=-1; } ...... <template name="edititemtemplate"> ...... <b>Price:</b><input id="edit_price" type="text"> . . .
这可以很方便地用在系统后台维护上。
问题,上例中模板中的控件刚好只有一个,所以FindControls起作用了,但如果有多个呢?
可以通过DataList的Items集合来遍历,如:
for(int i=0;i<MyDataList.Items.count;i++) String isChecked = ((CheckBox)MyDataList.Items[i].FindControls("save")).checked.ToString(); <template name="itemtemplate"> <asp:checkbox id="save" runat=server> </template>
9).商业控件
。应用的bin目录
在asp中的组件需要用regsvr32注册,不方便远程管理,ASP+中只需要放到应用的/bin目录下即可。
<%Import NameSpace="helloworld"%>引入名称空间,config文件来指定使用哪些控件,例:
<configuration> <compilation> <assemblies> <add assembly="System.Data"/> <add assembly="System.Web.Services"/> <add assembly="System.Drawing"/> <add assembly="*" /> </assemblies> </compilation> </configuration>
其中,前三个是全局的,最后一个是管bin目录下的。
10).写控件
略。
注意需要从Controls派生(System.Web.UI.Controls)
11).WebForms控件参考
两大类,
一是System.Web.UI.HtmlControls,以Html打头,多为Web页面上显示的。
二是System.Web.UI.WebControls,附加的,如DataGrid等。
具体略。
12).WebForms表达式参考
<%%>代码块,<%=%>也支持的。
<script runat="server">
服务器控件用:<asp:Lable .....runat="server">
Html服务器控件用: <span id="Message" runat="server">
数据帮定:<%# %>
对象:<object runat="server">,如:
<object id="items" class="System.collections.ArrayList" runat="server">
服务器端注释:<%-- comment --%>
服务器端包含:<--#include file="..." -->
三、asp+WEB服务
1).介绍
当今的web已经不再是提供访问了。
NGWS对ASP+提供了创建WEB服务的内在支持。
WEB服务文件以.asmx结尾,也是在一个web应用中,也用URI寻址,一个简单例子:
<%@ WebService Language="c#"%> using System.Web.Services; public class HelloWorld:WebService{ [WebMethod] public String SayHelloWorld(){ return "HelloWorld"; } }
用WebService指令标记,引入名称空间System.Web.Services,类从WebService派生,
[WebMethod]签署后面的方法保护给外部(如果用VB,则为<WebMethod>)。
访问:http://localhost/HelloWorld.asmx,可以使用多种协议,包括SOAP,HTTP GET等。
如果带参数?SDL,如helloWorld.asmx?SDL,则返回XML格式,基于SDL文件格式的一个描述信息。
SDL(Service Description Language).
NGWS带有工具创建WEB服务应用。客户访问WEB服务需要一个能懂得SDL文件格式的代理类,
NGWS提供工具WebServiceUtil.exe以创建这个代理类。
例: WebServiceUtil /c:proxy /pa:http://localhost/HelloWorld.asmx?SDL
创建了一个 HelloWorld.cs文件。这个文件跟先前的类很相似,也有相同的方法([WebMethod]
签署的方法),编译它,然后调用其中的方法,它将通过SOAP协议访问服务器上的类,然后返回
结果(呵呵,很像JAVA中的RMI,或者原来的DCOM)。
2).编写简单的WEB服务
<%WebService Language="c#" %> using System; using System.Web.Services; public class MathService{ [WebMethod] public int Add(int a,int b){ return a+b; } [WebMethod] public int Subtract(int a,int b){ return a-b; } }
直接在浏览器里调用MathService.asmx,将显示一个介绍页面,介绍了WEB服务能提供的服务
以及参数。如果带上参数?SDL访问,则返回一个SDL内容。
如果想把一个事先写好的类改成一个WEB服务,只需要另建一个asmx文件,且只有一行:
<%@ WebService class="MyWebApplication.MyWebService"%>
注意,因为服务也支持HTTP GET方式访问,所以我们可以直接在浏览器里测试我们的服务,
比如:
<form action="http://localhost/MathService.asmx/Add"> <input type="text" name="a"> <input type="text" name="b"> <input type=submit value="加"> </form>
3).WEB服务的类型
SOAP支持的可作为参数或返回值的类型有:
简单类型,如String,int32,Boolean,single等
列举类型,比如public enum color{red=1,blue=2}
简单类型或列举类型的数组
类和结构体,其属性或字段将被序列化以传输。
类数组
DataSet(ADO+中的DataSet),如果子类化DataSet,则不保险
Dataset数组
XmlNode及其数组
参数即可传值,也可传引用(这一点比RMI强)。
如果用HTTP协议,仅支持:
简单类型中的一部分
列举
简单类型或列举的数组
其实,HTTP协议传递时都是传的串么,这一点我们大家都很清楚。
如果在同一个asmx文件中定义了多个类,则需要在WebService中指定将哪一个作为WEB服务,
如:<%@ WebService Language="c#" Class="DataTypes"%>
4).在WEB服务中访问数据
然后用XML格式返回给客户,客户再重造表结构,如:
[WebMethod] public DataSet GetTitleAuthors(){ ..... DataSet ds = new DataSet(); ...... return ds; } 客户: DataService d = new DataServeice(); DataSet myData = d.GetTitleAuthors();
5).使用对象和属性
略
[WebMethod(EnableSession=False)]可以关闭SESSION,以提高性能。
五、asp+ MyWeb 应用
1).概述
MyWeb是ASP+中的一门新技术,允许一个ASP+应用在没有WEB服务器的机器上运行,实际在
IE内部运行,可以离线地运行。开发上与服务器端的应用开发无异。
让客户可以在需要时进行安装,这叫demand install。
当用户访问一个MYWEB应用时,ASP+首先试图从本地找到这个应用,如果找不到,则从
myweb:URL处下载应用说明(manifest),如果成功,则下载整个应用并安装到本地。
myweb在NGWS运行环境中执行(所以,客户端必须安装NGWS运行时库),可以访问独立的
存储系统,同时,可以建立到原来安装这个应用的站点的连接。他们不能访问本地机上的资源,
以及部分COM的调用(这有点类似于JAVA中的APPLET)。
2).myweb管理工具
如果安装了IE55,并且安装了NGWS运行时环境,则可以从浏览器工具条上选择"myweb"按扭,
(位置在工具条的最后,就像安装了金山词霸后增加的那个工具一样),或者也可以直接在浏览
器的地址栏里输入 myweb:// ,就可以进入MYWEB管理工具。
存在两种类型的myweb应用,一是Remote的,二是Local的。
可以用管理工具新安装一个myweb应用,或者直接从浏览器地址栏里输入myweb的URL,后一
种情况下,如果已经安装了这个myweb应用,则将直接启动该应用。
3).开发myweb应用
跟开发一个ASP+服务器应用类似,最后需要一个CAB文件,用实用工具cabarc.exe生成,如:
cabarc -p -r n myweb.cab *.aspx *.html *.jpg *.css *.dll *.web
manifest文件是OSD(Open Software Description)格式,名为myweb.osd,一个例子:
<softpkg name="Demo1" version="1.0"> <implementation> <codebase href="http://somewhere.com/myweb.cab"> </implementation> <homepage>myweb://somewhere.com/default.aspx</homepage> <Iconurl>myweb://somewhere.coom/icon.gif</Iconurl> <RemoteIconurl>http://somewhere.com/icon.gif</RemoteIconurl> <Author>white</Author> <Source> Beijing 123okey.Inc</Source> <size>3000</size> </softpkg>
4).略
5).独立存储空间
myweb不能访问本地文件系统,但可以访问由GNWS提供的独立存储空间(IsolatedStorage),
就像访问本地文件一样,例:
//读取数据 String _storeFile="mystore"; ArrayList values=new ArrayList(); IsolatedStorageFileStream stream = null; try{ stream = new IsolatedStorageFileStream(_storeFile,FileMode.Open); }catch(Exception e){} if(null!=stream){ values=(ArrayList)BinarySerializer.DeSerialize(stream); stream.Close(); } //保存数据 IsolatedStorageFileStream stream; stream = new IsolatedStorageFileStream(_stroeFile,FileMode.OpenOrCreate); ArrayList values = new ArrayList(); values.Add("test1"); ...... BinarySerializer.Serializer(values,stream); stream.Close();
使用上例时注意需要引入名称空间:
System.IO; System.IO.IsolatedStorage; System.Runtime.Serialization.Formatters;
6).离线数据同步
现在这个版本的myweb还不支持自动地实现同步。
可以用myweb.Connected属性判断当前是否连在网上。
六、Cache服务
Caching动态产生的内容叫output catching。
Caching专门的对象叫Data Catching。
asp+中提供了专门的Cache引擎。
1).output caching
设置response的expiration/validation,仅对GET和HEAD有效,支持URL中的参数,完全相同
时使用catching中的内容。内容缺省地将在cache中保存60分钟。
要让一个.aspx文件被caching,仅需要加一行:
<%@ OutputCache Duration="60" %>
上面的60指60秒。
要实现更多的控制,如下:
Response.Cache.SetExpires(DateTime.Now.AddSeconds(60)); Response.Cache.SetCacheability(HttpCacheability.Public);
或者:
SetExpires(DateTime.Now.AddSeconds(60)); SetCacheability(HttpCacheability.Public); SetSlidingExpiration(true);
2).Data Caching
Cache引擎可以让你把对象保存到其中,只有应用重启后才需要重建Cache。是一个字典接口,如:
Cache["mykey"]=myValue; myValue = Cache["mykey"]; if(myValue!=null) ......
还可以支持清除,过期等,以及文件和键值以来(可以用于统计图形,记数器等)。
例:
source = (DataView)Cache["MyDataSet"]; if(source == null){ ...... source = new DateView(ds.Tables[0]); Cache["MyDataSet"] = source; }
文件依赖:
Cache.Insert("MyData",source,new CacheDependency(server.mappath("authors.xml")));
时间过期:
Cache.Insert("MyData",source,null,DateTime.Now.AddHours(1),TimeSpan.Zero);
注意,为了防止资源访问中的冲突,必须对资源访问进行同步,如:
private static String CacheSynchronize;
lock(CacheSynchronize)
{......
}
七、配置
asp+中使用文件做配置。
在其中,也可以配置自己的信息。
1).配置文件格式
文件名为config.web,应用当前应用及其自目录下的应用。
WinNT\ComPlus\<version>\Config.web是整个系统的缺省配置。config.web不可能被浏览器
访问到,即便放在WEB应用的目录下。
配置文件中分成两小节,第一节指出谁来处理配置信息,第二小节是具体的配置数据。
标准的ASP+配置处理器有:
<httpmodules> 处理所有的请求
<httphandlers> 将特定的URL映射到特定的处理器,子目录中应用不继承该配置。参考前面
的http处理器和工厂。
<sessionstate> session状态处理器
<globalization>
<compilation> 编译相关的处理
<trace> asp+ Trace服务
<security> ASP+安全模块
<iisprocessmodel> iis处理模块
<browsercaps> 处理浏览器兼容信息的设置
2).获取配置信息
可以用API直接访问配置信息,比如Request.Browser对象的属性直接获得browsercapabilities
或者调用Context.GetConfig,比如:
CustomConfigSettings Config=(CustomConfigSettings)Context.GetConfig("customconfig"); if(config.Enabled==true) ......
GetConfig可有第二个参数获得指定的URL的配置。
下面是一个保存应用自己的配置数据的例:
<configuration> <configsections> <add name="databases" type="System.Web.Configuration.DictionarySectionHandler" /> </configsections> <databases> <add key="pubs" value="server=localhost;uid=sa;pws="/> <add key="nothwind" value="server=localhost;uid=sa"/> </databases> </configuration> 使用: String dsn = (String)((Hashtable)Context.GetConfig("databases"))["pubs"];
八、部署应用
VS7将一个project编译成一个DLL文件,是一个NGWS装配,一个装配可以用在一台机器上,放到
全局Cache,供所有的应用访问,也可以放到某个应用的装配Cache中,只让一个应用访问。
ASP+允许动态地引用一个类,只需要提供其装配和类名,格式:
assemlyname#classname
九、安全
1).认证和授权
除了利用Windows提供的认证服务外,ASP+还提供了一种服务,使基于 FORM的认证很方便地实现。
它是基于COOKIE工作的,所以客户浏览器必须支持COOKIE。需要注意的是,ASP+的认证服务是从属于
IIS的认证服务的。
ASP+提供两种类型的认证服务,一是基于文件的ACL的,另一种是基于URL的。基于URL的培植在
配置文件中。
配置<security>节中的<authentication>元素,可以有下面几种值:
none:没有认证
Windows:NT的用户/组
Cookie:将未认证的用户转向一个特定的登陆页面。最常用的一种方法。
Passport:必须安装PassPort服务。
例:
<configuration> <security> <authentication mode="Cookie"/> </security> </configuration>
2).基于Windows的认证
当采用它时,一个WindowsPrincipal对象被附加到Request对象中。程序中可以判定当前用户是否
某类角色,如:
if(User.IsInrole("Administrators"))
......
还可以取得用户名,如:
User.Identity.Name;
User.Identity.Type;
3).基于FORM的认证
a).选cookie模式,禁止匿名访问:
<authentication mode="Cookie"/> <authorization> <deny users="?"/> </authorization>
b).配置登陆页,加密用的键,以及Cookie名字,在<authentication>的子元素中:
<cookie decryptionkey="autogenerate" loginurl="login.aspx" cookie=".ASPXCOOKIESDEMO"/>
注意,loginurl可以是远程机器,但decryptionkey则在两台机器上的必须相同。descryptionkey
设成autogenerate则ASP+自动选择。但如果一台机器上有多个应用,则最好指定。同时,不同的应用
也该用不同的Cookie名字。因为同一台机器上的所有应用设置的Cookie都将被客户传回来,所以不能同名。
c).提供登陆页
d).验证完后(用你自己的验证机制,比如同数据库中的记录做比较),用下面一行:
CookieAuthentication.RedirectFromLoginPage(username,persistence)
返回登陆页前一页。
这一句也设定了Cookie,从而让它之后的ASP+认证服务认为用户已经经过了认证。
如果不想转向原来的页,而是出现特定的页,比如登陆用户可选菜单页,那必须使用另外的方法,
可以用CookieAuthentication.SetAuthCookie设置好Cookie,用CookieAutentication.GetAuthCookie
来获得Cookie.
另外,上面那行中的第二个参数是一个bool值,表示是否让Cookie永久保存,如果为false的话,
则当用户关闭浏览器后,cookie就消失了。
用CookieAuthentication.SignOut可以清除Cookie,对应用户退出登陆。
除了以上的用程序自己实现认证过程外,也可以用配置文件来实现让ASP+帮你完成验证。在
<authentication>节中:
<credentials passwordformat="SHA1"> <user name="white" password="ASPFSSA98527357"> </credentials>
然后程序调用CookieAuthenticationManager.Authenticate,提供用户名和口令作为参数,就可以
由ASP+帮你判定用户是否合法了。
加密算法支持 Clear,SHA1,MD5。
4).认证拥护的角色
可以针对用户,也可以针对角色(组),如:
<authorization> <allow users="towhite@263.net"/> <allow roles="Admins"/> <deny users="*"/>
多个用户名间用逗号","分割。 还可以细化请求方法: <allow verb="post" users="white,saillor"/> 其中,*代表任何人,?代表匿名用户。
十、国际化,本地化应用
ASP+内部使用UNICODE,NGWS内部基类的String也是用UNICODE。可以支持某种特定的编码,实现转换。
场所属性可以通过CultureInfo类访问,其中,CurrentCulture是同场所有关的函数的缺省值,
而CurrentUICulture是场所上的资源数据格式,例:
<%=CultureInfo.CurrentCulture.NativeName %> <%=CultureInfo.currentUICulture.NativeName %> 一些与场所有关的类提供格式化输出,如: <%=DateTime.Now.Format("f",null)%> <%=DateTime.Now.Format("f",new System.Globalization.CultureInfo("de"))%>
可以为某个目录进行配置,如:
<configuration> <globalization fileencoding = "utf-8" requestencoding = "utf-8" responseencoding = "utf-8" culture = "en-us" uiculture = "de" /> 或者在Page指令中: <%@ Page Culture ="fr" UICulture = "fr" ResponseEncoding = "utf-8" %>
在页面内部还可以随时更改,使用 Thread.CurrentCulture修改,也就是说,同一个页面可以使用
很多种编码输出。
1).设置文化和编码
中文的Culture应设为:zh-cn CultureInfo.CurrentCulture.Name = "zh-cn"; CultureInfo.CurrentCulture.EnglishName = "Chinese(Peoples' Republic of China"; CultureInfo.CurrentCulture.NativeName = "中文(简体)(中华人民共和国)"; 另外,类RegionInfo还提供地域信息: RegionInfo.CurrentRegion.NativeName = "中华人民共和国"; RegionInfo.CurrentRegion.CurrencySymbol = "¥";
2).本地化ASP+应用
3).使用资源文件
NGWS基类支持,运行时有个类叫ResourceManager的实例可以使用。可以用ResourceWriter或者实用
工具resgen.exe来生成资源文件,resgen以 key = value 的形式作为输入,如:
;
;注释
;
[Strings]
greetings = 欢迎你!
more = 更多新闻
资源文件的后缀为.resources。
如何在页面中使用资源文件?
用户的Content-Language可以用Request.UserLanguages[0]来取得。
如何实现多语言支持?
a).准备资源文件,生成.resources文件,文件取名规则:中间带Culture名。例:articles.en-us.resources
b).global.asax中取得一个ResourceManager,并放如Application中供整个Application使用
c).global.asax中为Application_BeginRequest事件写代码,根据客户的情况决定当前的Culture.
d).在页面中用ResourceManager.GetString取得内容。
例:
//global.asax中: void Application_OnStart(){ Application["RM"]=new ResourceManager("articles",Server.Mappath("resources")+Enviroment.DirectorySeparatorChar,null); } void Application_BeginRequest(Object sender,EventArgs e){ try { Thread.CurrentThread.CurrentCulture = new CultureInfo(Request.UserLanguages[0]); }catch(ArgumentException){ Thread.CurrentThread.CurrentCulture=new CultureInfo("en-us"); } Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture; } //default.asax中: ResourceManager rm; void Page_Init(Object sender,EventArgs e){ rm=(ResouceManager)Application["RM"]; } //输出内容时: <%= rm.GetString("greetings") %>