您的位置:首页 > 编程语言 > ASP

在ASP.NET中使用Session常见问题集锦

2006-09-25 03:01 507 查看
C#是一种简单、现代、面向对象和类型安全的编程语言,由C和C++发展而来。

C#(C Sharp发音为“C霎普”)牢固地植根于C和C++语言族谱中,并且会很快被C和C++程序员所熟悉。

C#的目标在于把Visual Basic的高生产力和C++本身的能力结合起来。

C#作为Microsoft Visual Studio 7.0的一部分提供给用户。

除了C#以外,Visual Studio还支持Visual Basic、Visual C++和描述语言VBScript和Jscript。

所有这些语言都提供对Microsoft .NET平台的访问能力,它包括一个通用的执行引擎和一个丰富的类库。

Microsoft .NET平台定义了一个“通用语言子集”(CLS),是一种混合语言,它可以增强CLS兼容语言和类库间的无缝协同工作能力。

对于C#开发者,这意味着既是C#是一种新的语言,它已经可以对用老牌工具如Visual Basic和Visual C++使用的丰富类库进行完全访问。C#自己并没有包含一个类库。

本章的其余部分描述这种语言的基本特性。

规范的“Hello,World”程序可以按照下面例子编写:

using System;

class Hello

{

static void Main() {

Console.WriteLine("Hello, world");

}

}

C#程序的源代通常存储在一个或多个扩展名为.cs的文件中,例如hello.cs。如果使用Visual Studio提供的命令行编译器,这样的程序可以用命令行命令来编译

csc hello.cs

这样就会生成一个名为hello.exe的可执行程序。程序的输出如下:

Hello, world

下面对这个程序进行详细的研究:

· 使用System;指令涉及到一个名称空间(namespace)叫作System,这是在Microsoft .NET类库中提供的。这个名称空间包括在Mian方法中使用的Console类。名称空间提供了一种用来组织一个类库的分层方法。使用“using”命令后,就可以无障碍地使用名称空间中的各种类型成员。“Hello,world”程序中使用的Console.WriteLine是System.Console.WriteLine的简写。

· Main方法是类Hello中的一个成员,它有static的说明符,所以它是类Hello中的一个方法而不是此类中的实例。

· 对于一个应用程序的主入口点-称开始执行的方法-通常是一个称为Main的静态方法。

· “Hello,world”的输出是通过使用类库产生的。语言本身并没有提供类库。作为替代,它使用一个通用类库,这个类库也可以被诸如Visual Basic和Visual C++的语言所使用。

对于C和C++开发者来说,会有兴趣知道对一些没有出现在“Hello,world”程序的东西。

· 程序没有把Main设为全局方法。在全局级别上不支持方法和变量;这些元素通常包含在类型声明当中(例如,类或结构的声明)。

· 程序中不使用“::”或“->”操作符。“::”不再是一个操作符,而“->”操作符也只是在程序的某个小片断中才会使用。操作符“.”用于符合名称,例如Console.WriteLine。

· 程序中不包括前向声明。因为声明的顺序不重要,所以不再需要前向声明。

· 程序中不使用#include关键字。程序中的从属关系是象征性的而不是字面上地。这个系统消除了在用不同语言编写的程序间的障碍。例如,Console类可以用另外一种语言编写。
http://c.blog.51cto.com/post/325/2006 Wed, 01 Feb 2006 20:06:59 +0000 一些关于Session的问题,下面做一个总结,希望对大家有所帮助:

原文:http://blog.csdn.net/cuike519/archive/2005/09/27/490316.aspx

问:为什么Session在有些机器上偶尔会丢失?

答:可能和机器的环境有关系,比如:防火墙或者杀毒软件等,尝试关闭防火墙。

问:为什么当调用Session.Abandon时并没有激发Session_End方法?

答:首先Session_End方法只支持InProc(进程内的)类型的Session。其次要激发Session_End方法,必须存在Session(即系统中已经使用Session了),并且至少要完成一次请求(在这次请求中会调用该方法)。

问:为什么当我在InProc模式下使用Session会经常丢失?

答:该问题通常是由于应用程序被回收导致的,因为当使用进程内Session时,Session是保存在aspnet_wp进程中,当该进程被回收Session自然也就没有了,确定该进程是否被回收可以通过查看系统的事件查看器获得信息。

具体信息请参考:

Session variables are lost intermittently in ASP.NET applicationshttp://support.microsoft.com/default.aspx?scid=kb;en-us;Q316148

在1.0的时候也有一个bug会导致工作进程被回收并重启,该bug已经在1.1和sp2中修复。

关于该bug的详细信息请参考:

ASP.NET Worker Process (Aspnet_wp.exe) Is Recycled Unexpectedly. http://support.microsoft.com/default.aspx?scid=kb;en-us;Q321792

问:为什么当Session超时或者Abandoned后,新Session的ID和原来的相同?

答:因为SessionID是保存在客户端浏览器的实例里,当Session超时在服务器重新建立Session时,将使用浏览器传来的SessionID,所以当Session超时后,再重新建立后SessionID并不变。

问:为什么每次请求的SessionID都不相同?

答:该问题可能是没有在Session里面保存任何信息引起的,即程序中任何地方都没有使用Session。当Session中保存信息之后SessionID将一直和浏览器相关,此时的SessionID将不会在变化。

问:ASP和ASP.NET之间是否可以共享Session?

答:可以。但是这是一个比较复杂的过程,微软提供了官方的解决方案,请参考:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/ConvertToASPNET.asp

问:什么类型的对象可以保存在Session里?

答:这依赖使用的Session的模式,当使用的是进程内(InProc)的Session那么可以轻松的保存任何对象。如果你使用了非InProc的模式,则只能保存可以序列化和反序列化的对象,如果此时保存的对象不支持序列化,则不能保存到这种模式(非InProc)的Session里。

问:为什么在Session_End中不能使用Response.Redirect和Server.Transfer方法跳转页面?

答:Session_End是一个在服务器内部激发的事件处理函数。它是基于一个服务器内部的计时器的,在激发该事件时服务器上并没有相关的HttpRequest对象,因此此时并不能使用Response.Redirect和Server.Transfer方法。

问:在Session_End中是否可以获得HttpContext对象?

答:不行,因为这个事件并没有和任何的请求(Request)相关联,没有基于请求的上下文。

问:在Web Service中该如何使用Session?

答:为了在Web Service中使用Session,需要在Web Service的调用方做一些额外的工作,必须保存和存储调用Web Service时使用的Cookie。详细信息请参考MSDN文档的HttpWebClientProtocol.CookieContainer属性。然而,如果你使用代理服务器访问Web Service由于框架的限制,两者不能共享Session。

问:在自定义自己的HttpHandler的时候,为什么不能使用Session?

答:在实现自己的HttpHandler的时候,如果希望使用Session必须实现下面的两个标记接口中的一个:IRequiresSessionState和IReadOnlySessionState,这些接口没有任何方法需要实现,只是一个标记接口和使用INamingContainer接口的方法一样。

问:当我使用webfarm时,当我重定向到其他的Web服务器时Session为什么会丢失?

答:详细信息请参考:

PRB: Session State Is Lost in Web Farm If You Use SqlServer or StateServer Session Modehttp://support.microsoft.com/default.aspx?scid=kb;en-us;325056

问:为什么我的Session在Application_OnAcquireRequestState方法中无效?

答:Session只有在HttpApplication.AcquireRequestState事件调用以后才会有效。

详细信息请参考:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconhandlingpublicevents.asp

问:如果使用了cookieless,我该如何从HTTP页面定向到HTTPS?

答:请尝试下面的方法:

String originalUrl = "/fxtest3/sub/foo2.aspx";

String modifiedUrl = "https://localhost" + Response.ApplyAppPathModifier(originalUrl);

Response.Redirect(modifiedUrl);

问:Session在global.asax中的那些事件中有效?

答:Session只有在AcquireRequestState事件之后有效,该事件之后的事件都可以使用Session。

问:如何获得当前Session中保存的所有对象?

答:可以通过遍历所有的Session.Keys来获得。代码如下:

ArrayList sessionCollection = new ArrayList();

foreach (string strKey in Session.Keys){

sessionCollection.Add(Session[strKey]);

}

问:是否可以在不同的应用程序中共享Session?

答:不能直接共享。可以参考如何在ASP和ASP.NET之间共享Session。

问:Session.Abandon和Session.Clear有何不同?

答:主要的不同之处在于当使用Session.Abandon时,会调用Session_End方法(InProc模式下)。当下一个请求到来时将激发Session_Start方法。而Session.Clear只是清除Session中的所有数据并不会中止该Session,因此也不会调用那些方法。

问:为了可以顺序访问Session的状态值,Session是否提供了锁定机制?

答:Session实现了Reader/Writer的锁机制:

当页面对Session具有可写功能(即页面有<%@ Page EnableSessionState="True" %>标记),此时直到请求完成该页面的Session持有一个写锁定。

当页面对Session具有只读功能(即页面有<%@ Page EnableSessionState="ReadOnly" %>标记),此时知道请求完成该页面的Session持有一个读锁定。

读锁定将阻塞一个写锁定;读锁定不会阻塞读锁定;写锁定将阻塞所有的读写锁定。这就是为什么两个框架中的同一个页面都去写同一个Session时,其中一个要等待另一个(稍快的那个)完成后,才开始写。

问:Session平滑超时意味着什么?

答:Session平滑超时意味着只要你的页面访问(使用)了Session,超时时间将被刷新(可以理解为重新计时),即从该页面请求开始,将重新计算超时时间。但是,该页面不能禁用Session。它会自动的访问当前页面的Session,刷新超时时间。

问:在global.asax中的事件处理函数中Session为什么无效?

答:依赖于在哪个事件处理函数中使用Session,Session在AcquireRequestState事件之后才有效,该事件之后的所有事件处理函数都可以使用Session,之前的则不能。

问:当我写一个依赖于当前应用的Session的组件时,为什么不能直接使用Session["Key"]获得其值?

答:Session["Key"]实际上是this.Session["Key"],它是作为Page的一个属性提供的,所以在你的组件中不能直接使用这个属性。你可以通过下面的方式使用Session:

HttpContext.Current.Session["Key"] = "My Seesion Value";

问:当我使用InProc模式保存Session时,此时的Session是保存在哪里?

答:不同的IIS的处理方式不同,

当使用的是IIS5的时候Session是保存在aspnet_wp.exe的进程空间里的。

当使用的是IIS6时,默认情况下所有的应用程序共享应用程序池,Session保存在w3wp.exe的进程空间中。

问:Session的超时设置是分钟还是秒?

答:是分钟,默认为20分钟。

问:当页面出现错误后我的Session是否将被保存?我需要在Session_End中处理一些清理工作,但是失败了,为什么?

答:Session_End只有在Session运行在InProc模式下才会被执行。Session_End使用的帐号是运行aspnet_wp工作进程的帐号(这个可以在machine.config中设置)。因此,如果在Session_End方法里,使用集成安全性链接到SQL,它将使用aspnet_wp进程的帐号打开链接,此时成功与否则依赖于你的SQL的安全性设置。

问:为什么当我设置cookieless为true是我在重定向的时候会丢失Session?

答:当使用cookieless时,你必须使用相对路径替换程序中的绝对路径,如果使用绝对路径ASP.NET将无法在URL中保存SessionID。

例如:将myDirmySubdirdefault.aspx换成..default.aspx即可。

问:如何将SortedList存储到Session或者Cache里?

答:请参考下面的方法:

SortedList x = new SortedList();

x.Add("Key1", "ValueA");

x.Add("Key2", "ValueB");

保存到Session中:

Session["SortedList1"] = x;

使用下面方法获得之:

SortedList y = (SortedList) Session["SortedList1"];

Chahe则同理。

问:我为什么会获得这样的错误信息“Session state can only be used when enableSessionState is set to true, either in a configuration file or in the Page directive”?

答:这个问题可能在一个已经安装了Microsoft Visual Studio .NET开发环境的机器上,再安装Window Sharepoint Server(WSS)后出现。

WSS ISAPI过滤器会处理所有的请求。当你通过虚拟目录浏览一个ASP.NET的应用程序时,ISAPI过滤器不会给文件夹目录分配URL。

解决方法是:不要再安装了WSS的机器上使用Session。

详细信息请参考:

Session state cannot be used in ASP.NET with Windows SharePoint Serviceshttp://support.microsoft.com/default.aspx?scid=kb;en-us;837376

问:如何删除Session变量?

答:想要删除Session变量可以使用HttpSessionState.Remove()方法。

问:是否有办法知道应用程序的Session在运行时占用了多少内存?

答:没有。目前这个值时无法考证的,至少我现在还没有看到这方面的资料。但是可以通过性能监视器以及程序代码大概估算出来一个值。

问:当页面中是否了frameset,发现在每个frame中显示页面的SessionID在第一次请求时都不相同,为什么?

答:原因是你的frameset是放在一个htm页面上而不是ASPX页面。

在一般情况下,如果frameset是aspx页面,当你请求页面时,它首先将请求发送到Web服务器,此时已经获得了SessionID,接着浏览器会分别请求Frame中的其他页面,这样所有页面的SessionID就是一样的,就是FrameSet页面的SessionID。

然而如果你使用Html页面做FrameSet页面,第一个请求将是HTML页面,当该页面从服务器上返回是并没有任何Session产生,接着浏览器会请求Frame里面的页面,这样这些页面都会产生自己的SessionID,所以在这种情况下就会出现这种问题。当你重新刷新页面时,SessionID就会一样,并且是最后一个请求页面的SessionID。

问:是否可以将不同应用程序的Session保存在相同的SQL Server服务器的不同数据库上。

答:可以,请参考:

FIX: Using one SQL database for all applications for SQL Server session state may cause a bottleneckhttp://support.microsoft.com/default.aspx?scid=kb;en-us;836680

问:在Session_End是我是否可以获得有效的HttpSessionState和HttpContext对象?

答:你可以在这个方法中获得HttpSessionState对象,可以直接使用Session来访问即可。但是不能获得HttpContext对象,因为该事件并没有和任何请求相关联,因此不存在上下文对象。

问:在SQLServer模式下使用Session,为什么我的Session不过期?

答:在SqlServer模式下,Session的过期是通过SQL Agent的注册工作完成的,请检查你的SQL Agent是否运行?

问:当我设置EnableSessionState为“ReadOnly”后,但是我在InProc模式下依然可以修改Session的值,这是为什么?

答:即使EnableSessionState标示为ReadOnly,但是在InProc模式下用户依然可以编辑Session。唯一不同的是,在请求过程中Session将不会被锁住。

问:我如何才能避免在链接SQL时指定密码?

答:使用信任链接或者使用加密的链接串。有关这方面的详细信息请参考:

How To Use the ASP.NET Utility to Encrypt Credentials and Session State Connection Strings http://support.microsoft.com/default.aspx?scid=kb;en-us;329290

问:我在我自己的类中该如何使用Session呢?

答:可以使用HttpContext.Current.Session方式使用,具体方法如下:

HttpContext.Current.Session["SessionKey"] = "SessionValue";

类似的你还可以使用这种方式使用Application对象。

问:为什么在切换成SQLServer模式后我的请求被挂起了?

答:检查在Session里面是否都保存的是可以保存在SQLServer模式下的对象,即这些对象必须支持序列化。

问:当Session设置成cookieless后会有什么影响?

答:当把cookieless设置成true时,主要会有下面的约束:

1、在页面中不能使用绝对链接

2、在应用程序中在除了Http和Https之间的切换时需要完成一些其他的步骤。

如果发送一个链接给其他人,此时的URL里面将包含Session ID的信息,所以两个人将公用一个Session。

问:是否可以将Session保存在数据库中?

答:当然可以,详细信息请参考:http://support.microsoft.com/default.aspx?scid=kb;en-us;311209 http://c.blog.51cto.com/post/325/1981 Fri, 27 Jan 2006 12:42:03 +0000
运行环境:

IBM T30

CPU:1.8GHZ

内存:256M

硬盘:40G

OS:Windows Server 2000 SP4

Visual Studio .NET 2003(Framework v1.1.4322)

Microsoft SQL Server 2000

机器配置跑不动 VS2005,很是郁闷,故本次旅行仅限制在Framework v1.1.4322。

废话少说,第一个例子,使用记事本编写C#语句输出XML文件。

第一步:打开记事本,输入以下代码。

// 文件test001.cs

using System;

using System.Xml;

public class Hello51CTO {

public static void Main(string [ ] args) {

XmlTextWriter writer = new XmlTextWriter(Console.Out);

writer.WriteStartDocument( );

writer.WriteElementString("网址", "http://c.blog.51cto.com/");

writer.WriteEndDocument( );

writer.Close( );

}

}

// 文件test001.cs结束

第二步:打开一个DOS窗口(运行,CMD,回车),我们使用如下命令行编译test001.cs

C:WINNTMicrosoft.NETFrameworkv1.1.4322csc /debug /target:exe test001.cs

// csc是C#的编译器,生成一个同名的exe文件test001.exe

// 参数/debug 是让编译器生成一个包含调试信息的附加文件test001.pdb

第三步:如果编译成功,则会生成两个文件test001.exe和test001.pdb,我们在DOS窗口下输入test001,运行刚刚生成的文件,可以看到输出如下内容:

<?xml version="1.0" encoding="gb2312"?><网址>http://c.blog.51cto.com/</网址>

怎么样,我们用记事本输出了一个简单的XML文件。
http://c.blog.51cto.com/post/325/1918 Sat, 21 Jan 2006 00:40:04 +0000 1、一般而言,如果想给aspx页面上的web form control加上一些javascript的特性,可以用Attributes.Add来实现。

  例如,对TextBox txt,可以:

txt.Attributes.Add("onclick", "fcn0();");

  那么,在web页面上click它的时候,就会调用fcn0这个javascript函数。

1.1、例外的情况是,对于IDE无法辨认的属性的解析。

  比如对一个RadioButton rbt,IDE不能辨认onclick这个属性,那么,类似上面的语句,

rbt.Attributes.Add("onclick", "fcn1(this);");

在.net framework 1.1中,将解析成

<input type=radio id=rbt onclick="fcn1(this);">...

而在在.net framework 1.0中,将解析成

<span onclick="fcn1(this);"><input type=radio id=rbt>...</span>

注意到,fcn1中,参数this对应的对象就不同了。这是一个细微的差别。

2、而对于HTML control,需要多做一点事情。

  在设计aspx页面的时候,从工具栏拖一个web form control,比如说,TextBox到页面,会发生两件事:

    一、aspx页面多一句

<asp:TextBox id="TextBox1" style="..." runat="server" Width="102px" Height="25px"></asp:TextBox>

    二、code behind多一句

protected System.Web.UI.WebControls.TextBox TextBox1;

  如果是html control,那么,第一句中,runat="server"不会出现,而第二局不会被自动添加。

  因此,如果要访问html control,需要

    一、aspx页面的语句中添加runat="server"属性,成为

<INPUT style="..." type="text" size="9" id="htxt" runat="server">

    二、code behind中显示的声明

protected System.Web.UI.HtmlControls.HtmlInputText htxt;

  注意到第一句的id和第二句的变量名是相同的。

2.1、注意到,前面System.Web.UI.WebControls.TextBox对应的html control是System.Web.UI.HtmlControls.HtmlInputText,对应的html的tag是<INPUT type="text">,

相应的,html的tag <body>对应的html control是

public System.Web.UI.HtmlControls.HtmlGenericControl myBody;

2.2、有一点例外的是html的<form> tag对应的onsubmit的事件。看这样一个aspx页面

<%@ Page language="c#" Codebehind="WebForm2.aspx.cs" AutoEventWireup="false" Inherits="TestCs.WebForm2" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >

<HTML>

<HEAD>

<title>WebForm2</title>

<meta name="GENERATOR" Content="Microsoft Visual Studio 7.0">

<meta name="CODE_LANGUAGE" Content="C#">

<meta name="vs_defaultClientScript" content="JavaScript">

<meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">

<script language="javascript">

function fcn1()

{

prompt("hi", "fcn1");

}

</script>

</HEAD>

<body MS_POSITIONING="GridLayout">

<form id="WebForm2" method="post" runat="server" onsubmit="fcn1();">

<asp:Button id="Button1" style="Z-INDEX: 103; LEFT: 423px; POSITION: absolute; TOP: 83px" runat="server" Width="86px" Height="29px" Text="Button"></asp:Button>

<asp:DropDownList id="DropDownList1" style="Z-INDEX: 104; LEFT: 284px; POSITION: absolute; TOP: 163px" runat="server" Width="188px" Height="17px" AutoPostBack="True">

<asp:ListItem Value="a">a</asp:ListItem>

<asp:ListItem Value="b">b</asp:ListItem>

<asp:ListItem Value="c">c</asp:ListItem>

</asp:DropDownList>

</form>

</body>

</HTML>

内容很简单,定义了一个javascript函数fcn1,放了一个Button Button1和一个autopostback的Dropdownlist DropDownList1,运行它,可以看到:点击Button1,会先执行fcn1然后postback,而选择DropDownList1的不同选项,将只会postback,而不会触发fcn1。

  微软autopostback=true的webcontrol实现postback,原理是这样的:

    一、如果此aspx页面有autopostback=true的webcontrol,那么会写下面一段javascript语句定义一个叫__doPostBack的javascript函数。

<script language="javascript">

<!--

function __doPostBack(eventTarget, eventArgument) {

var theform;

if (window.navigator.appName.toLowerCase().indexOf("netscape") > -1) {

theform = document.forms["WebForm2"];

}

else {

theform = document.WebForm2;

}

theform.__EVENTTARGET.value = eventTarget.split("$").join(":");

theform.__EVENTARGUMENT.value = eventArgument;

theform.submit();

}

// -->

</script>

    二、例如是上面的dropdownlist,将会render成:

<select name="DropDownList1" onchange="__doPostBack('DropDownList1','')" language="javascript" id="DropDownList1" style="...">

<option value="a">a</option>

<option value="b">b</option>

<option value="c">c</option>

</select>

这样,通过javscript调用theform.submit();来submit form,postback,但是,theform.submit将不会触发form的onsubmit事件!

  这是微软的一个bug。

  解决的方法可以看这里:http://www.devhawk.net/art_submitfirefixup.ashx,这里提供了一个dll及源代码,使用的时候,在project的reference里加入这个dll,然后在web.config中加上一段

<httpModules>

<add type="DevHawk.Web.SubmitFireFixupModule,SubmitFireFixupModule" name="SubmitFireFixupModule" />

</httpModules>

就可以了。

3、一个应用。

  常常听到抱怨,说如果在Browser端用javascript改动了某个<select>元素,那么,它对应的Server端的DropDownList不能得知这个更新。

  这种情况可能出现在“级联”的DropDownList中,比如第一个DropDownList是省份,第二个是城市;也可能出现在,从第一个DropDownList选择某些项加入到第二个DropDownList中。

  对此使用以上的技术,我做了一个这样的解决方案(类似于ViewState的方法):

    一、我定义了一个长宽都是0的TextBox txtWrap,并把所有我想处理的DropDownList都加上AthosOsw="True" 这样的属性,准备处理。

    二、参照上面2.2的内容,我加入了SubmitFireFixupModule,来保证触发form的onsubmit事件。

    三、form的onsubmit事件将执行javascript函数fcnAthosOnSubmitWrap,它将遍历AthosOsw属性为True的DropDownList,记下数据,最后合并起来放到txtWrap里,其实这就是一个序列化的过程。代码如下:

function fcnAthosOnSubmitWrap()

{

txtWrap = document.all["txtWrap"];

var i;

var strWrap = '';

for(i=0;i<document.all.length;i++)

{

ctrl = document.all[i];

if(ctrl.tagName.toUpperCase() == 'SELECT' && typeof(ctrl.AthosOsw) != 'undefined' )

{

if(ctrl.AthosOsw.toUpperCase() == 'TRUE')

{

strWrap += fcnAthosWrapSelect(ctrl) + '&&&';

}

}

}

if(strWrap.length>3)

txtWrap.value = strWrap.substring(0, strWrap.length-3);

};

//AthosOsw

function fcnAthosWrapSelect(ctrlSelect)

{

var i;

var strWrapSelect = ctrlSelect.id + '&' + ctrlSelect.tagName;

var strValue='';

var strText='';

for(i=0; i<ctrlSelect.options.length; i++)

{

strValue = ctrlSelect.options[i].value;

strText = ctrlSelect.options[i].text;

strWrapSelect += '&&' + i + '&' + strValue.replace(/&/g, '%26') + '&' + strText.replace(/&/g, '%26');

};

return strWrapSelect;

};

    四、form的Page_Load中调用clsCommon.UnwrapControl(this, txtWrap.Text);来反序列化。clsCommon是我的工具类,UnwrapControl方法代码如下:

static public void UnwrapControl(System.Web.UI.Page pgUnwrap, String strUnwrap)

{

Regex r3 = new Regex("(&&&)"); // Split on hyphens.

Regex r2 = new Regex("(&&)"); // Split on hyphens.

Regex r1 = new Regex("(&)"); // Split on hyphens.

String[] sa3, sa2, sa1;

String s3, s2, s1;

int i3, i2, i1;

String strId, strTagName;

System.Web.UI.Control ctrlUnwrap;

DropDownList ddlUnwrap;

ListItem liAdd;

s3 = strUnwrap;

sa3 = r3.Split(s3);

for(i3=0;i3<(sa3.Length+1)/2;i3++)

{

s2 = sa3[i3*2];

if(s2.Length>0)

{

sa2 = r2.Split(s2);

if(sa2.Length>1)

{

s1 = sa2[0];

sa1 = r1.Split(s1);

if(sa1.Length==3)

{

strId = sa1[0];

strTagName = sa1[2];

ctrlUnwrap = pgUnwrap.FindControl(strId);

if(ctrlUnwrap !=null)

{

if(strTagName == "SELECT")

{

ddlUnwrap = (DropDownList)ctrlUnwrap;

ddlUnwrap.Items.Clear();

for(i2=1; i2 < (sa2.Length+1)/2;i2++)

{

s1 = sa2[i2*2];

sa1 = r1.Split(s1);

liAdd = new System.Web.UI.WebControls.ListItem(sa1[4],sa1[2]);

ddlUnwrap.Items.Add(liAdd);

}

}

}

}

}

}

}

}
http://c.blog.51cto.com/post/325/1884 Thu, 19 Jan 2006 21:18:35 +0000 建议下载VS.Net 2005企业版(cs_vs_2005_vsts_trial_dvd.iso.torrent)和SQLServer2005英文版(en_sql_2005_ent_x86_dvd.iso.torrent),还有MSDN也不要落下哦...VS05各版都是中文的

请点击下载种子

http://c.blog.51cto.com/get/325/vs2005.rar

cs_vs_2005_pro_dvd.iso.torrent

Visual Studio 2005 Professional Edition - DVD - (Simplified Chinese)

cs_vs_2005_vsts_trial_dvd.iso.torrent

Visual Studio 2005 Team Suite Trial Edition - DVD - (For Evaluation Only) (Simplified Chinese)

cs_vwd_2005_express.iso.torrent

Visual Web Developer 2005 Express Edition (Simplified Chinese)

cs_msdn_vs_2005_dvd.iso.torrent

MSDN Library for Visual Studio 2005 - DVD (Simplified Chinese)

cs_visio_enterprise_architects_2005.iso.torrent

Visio for Enterprise Architects (Visual Studio 2005) (Simplified Chinese)

en_sql_2005_ent_x86_dvd.iso.torrent

SQL Server 2005 Enterprise Edition - 32-bit - DVD (English)

注:VS2005是180day试用版,但添加注册码升级到正式版,然后点升级就OK了!

SN:KYTYH-TQKW6-VWPBQ-DKC8F-HWC4J
http://c.blog.51cto.com/post/325/1851 Thu, 19 Jan 2006 00:55:04 +0000 ADO.NET提供了两个主要的类来读取数据。通过本文我们可以学习如何在两者之间进行选择。

我经常听到有人问这个问题:“在ASP.NET Web应用程序中我应该用DataReader类还是DataSet类呢?”在很多文章以及新闻组的贴子中我经常看到这样的误解,即认为DataReader(SqlDataReader或OleDbDataReader的缩写)比DataSet好。有时候我也会看到相反的说法。事实上,Microsoft创建了这两个数据存取类是因为它们都是我们所需要的。每个类都有其优点和不足,你可以根据应用环境来选择用哪一个。

本文就两者的选择问题做了很清楚的讲述,可以让你在运用ASP.NET时,在选择DataReader类或DataSet类的方面得到一些指南。在基于客户端的Windows Form应用程序环境下,这些规则可能会改变。我在做这些讲述时,假设你已经用过DataReader和DataSet类了,并对它们很熟悉。

运用DataReader类

下面就是运用DataReader类的理想条件: 你读取的数据必须是新的,所以在每次需要数据的时候,你都必须从数据库读取。创建一个DataReader类不会消耗很多内存,不过随着负荷的增加,DataSet上的性能也会很快地提高(参考资源中Visual Studio Magazine中的文章)。

你对每行数据的需求很简单。该情况的最好的例子就是简单地将DataReader绑定到一个Web控件,如DataGrid或DropDownList。

你只需要从数据库中以只向前的(forward-only) 、只读的形式来存取XML数据。在这种情况下,你可以用SQLCommand对象的ExcecuteXmlReader()方法来得到一个XmlReader类(相当于XML版的DataReader)。这就需要一个运用FOR XML子句的SQL Server查询,或者一个包含有效XML的ntext字段。

你计划对数据库进行几个重复的调用,来读取一小块信息。在这种情况下,我们前面提到过的性能数据会有更大的提高。

的确,使DataSet类更强大的许多功能只适用于基于客户端的Windows Form应用程序,比如在多个表之间建立关系的功能。在很多情况下,DataSet类都比DataReader类更有优势,而且在有些情况下,你根本就不能用DataReader类。

运用DataSet类

在下面的情况,你应该考虑运用DataSet类: 你构建了一个Web service,它运用的数据是你作为返回值读取的数据。因为DataReader类必须保持到数据库的连接,所以它们不能被序列化到XML中,也不能被发送给一个Web service的调用者。

你需要排序或筛选数据。在运用一个DataView对象(呈现为DataTable类的DefaultView属性,它包含一个DataSet类)来排序或筛选数据前,我们先试着用SQL查询(如WHERE和ORDER BY语句)来实现这些功能,并运用更轻量级、更快的DataReader类。然而,有时侯用这种方法是不行的,或者当你需要多次地对数据进行排序或筛选时就不能用DataReader。

针对同一请求,你需要多次遍历数据。你只能在DataReader中循环一次。如果你想将多个ServerControl类绑定到同一个数据集,那么选择DataSet就更好。DataReader类不能被绑定到多个ServerControl类,因为它是只向前读取的。在这种情况下,如果要使用DataReader,必须从数据库读取两次数据。

你需要存储数据,而后续的页面请求可能会用到的这些数据。如果数据只被请求它的专门的人使用,你可以将DataSet类保存在一个Session变量中。如果数据可以被任何人访问,那么你可以将它保存在一个Application变量中,或保存在Cache中(我建议使用后一种方法,因为它支持时间期限和回调(callback))。因为DataReader类必须一直打开对数据库的连接,而且它一次只能保存一行数据,所以它们不能在跨页面请求中被保存。

你需要对一个结果集的每个元素实现特殊的、耗时的功能。例如,如果你从一个数据库读取一列邮政编码,并想通过调用一个Web service来得到每个地区的详细的天气状况信息,那么选择DataSet就会更好。这是因为,当你在用DataReader类时,在关闭DataReader类前,与数据库的连接不会被释放回连接池。在数千页面请求之间潜在的一个很小的延时都会造成Web应用程序的很高的访问量,从而就会消耗完可用的连接。相反,DataSet可以在前端读取所有的数据,并可以马上关闭与数据库的连接,将它返回到连接池,因此其它的页面请求就可以用这个连接了。

你需要在一个两维范例中加载并处理XML数据。DataSet类对于XML很有用,因为你可以将DataView用于XML,对根本的数据进行排序和筛选,就同处理一个数据库结果集一样。然而,需要注意的是在System.Xml名字空间中有很多类,你可以将它们用于更复杂的XML操作。

你的数据源不是一个数据库。虽然OleDbDataReader可以用于任何OLEDB数据提供者(可能指向一个数据库,也可能不指向一个数据库),但DataSet对象可以从一个XML文件直接加载数据,并动态地解释它的schema。DataSet类也可以将XML数据写回一个数据流或一个文件。

从上面的讲述我们就可以看到,DataSet类比DataReader类有更多的功能,这就可以让你在更多的情况下运用它们。但这并不意味着你总是在用DataSet类。你需要在ASP.NET中完成的相当大一部分的任务都属于DataReader的范畴。

尽管如此,毫无疑问,从重要程度或复杂程度的角度来说,DataSet类在很多ASP.NET Web应用程序中都起着很重要的作用。你可以通过明智的缓存来最小化数据库往返,从而降低DataSet类的“性能损害”。DataReader和DataSet都是一个成功的ASP.NET Web应用程序的重要的部件。重要的是,我们需要了解何时、在哪里可以最好的使用它们。
http://c.blog.51cto.com/post/325/1840 Wed, 18 Jan 2006 09:05:25 +0000
WMI 是 Windows Management Instrumentation 。

主要功能是:

访问本地主机的一些信息和服务,可以管理远程计算机,比如:获取磁盘信息,获取磁盘大小,获取网卡地址,获取CPU信息,获取硬盘型号,共享目录,重启,关机,创建进程,关闭进程等。(前提是你拥有足够的权限)呵呵,很强大吧。

使用方法:

很简单,在项目中引用 System.Management.dll 即可。

下面给出部分代码:

private void Page_Load(object sender, System.EventArgs e)

{

TextBox1.Text += getdisk();

TextBox1.Text += getmacaddress();

TextBox1.Text += cpuinfo();

TextBox1.Text += hardinfo();

TextBox1.Text += baseboard();

}
/// <summary>

/// 获取磁盘信息

/// </summary>

/// <returns></returns>

public string getdisk()

{

// disk["DriveType"] 的返回值意义如下:

// 1 No type

// 2 Floppy disk

// 3 Hard disk

// 4 Removable drive or network drive

// 5 CD-ROM

// 6 RAM disk

string a="";

SelectQuery query=new SelectQuery("Select * From Win32_LogicalDisk");

ManagementObjectSearcher searcher=new ManagementObjectSearcher(query);

foreach(ManagementBaseObject disk in searcher.Get())

{

a += (" "+disk["Name"] +" "+disk["DriveType"] + " " + disk["VolumeName"]) + diskinfo(disk["Name"].ToString()) +"n";

}

return a;

}

/// <summary>

/// 获取磁盘大小

/// </summary>

/// <param name="d"></param>

/// <returns></returns>

public string diskinfo(string d)

{

string a="";

ManagementObject disk = new ManagementObject("win32_logicaldisk.deviceid='"+d+"'");

disk.Get();

a = (" " + disk["Size"] + " bytes");

return a;

}

/// <summary>

/// 获取网卡地址

/// </summary>

/// <returns></returns>

public string getmacaddress()

{

string a="";

ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");

ManagementObjectCollection moc = mc.GetInstances();

foreach(ManagementObject mo in moc)

{

if((bool)mo["IPEnabled"] == true)

a = "网卡:" + mo["MacAddress"].ToString() + "n";

mo.Dispose();

}

return a;

}

/// <summary>

/// 获取CPU信息

/// </summary>

/// <returns></returns>

public string cpuinfo()

{

string a="";

ManagementClass mcobject = new ManagementClass("Win32_Processor");

ManagementObjectCollection moc = mcobject.GetInstances();

foreach(ManagementObject mo in moc)

{

a += "CPU:" + mo.Properties["ProcessorId"].Value.ToString() + "n";

}

return a;

}

/// <summary>

/// 获取硬盘型号

/// </summary>

/// <returns></returns>

public string hardinfo()

{

string a="";

ManagementClass mcobject = new ManagementClass("Win32_DiskDrive");

ManagementObjectCollection moc = mcobject.GetInstances();

foreach(ManagementObject mo in moc)

{

a += "硬盘型号:" + mo.Properties["Model"].Value.ToString() + mo.Properties[""].Value.ToString() + "n";

}

return a;

}

public string baseboard()

{

string a="";

SelectQuery query=new SelectQuery("SELECT * FROM Win32_BaseBoard");

ManagementObjectSearcher searcher=new ManagementObjectSearcher(query);

foreach(ManagementBaseObject disk in searcher.Get())

{

a += "主板制造商: "+disk["Manufacturer"] +"n型号: "+disk["Product"] + "n序列号: " + disk["SerialNumber"] +baseinfo() +"n";

}

return a;

}

public string baseinfo()

{

string a="";

SelectQuery query=new SelectQuery("Select SerialNumber From Win32_BIOS");

ManagementObjectSearcher searcher=new ManagementObjectSearcher(query);

foreach(ManagementBaseObject disk in searcher.Get())

{

a = disk["SerialNumber"].ToString();

}

return a;

}

参考资料

msdn WMI SDK:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/wmi_reference.asp
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: