置顶随笔

在工作中遇到些数据库数据查询效率问题,现在想请教下各位"老鸟"们.

怎么写去优化的查询SQL语句.比如:

二张都是2到3千万数据的表(A_Tabel 和 B_Table)

A_Table 有字段 add_time(日期类型);msgid(varchar型)
B_Table 有字段 stat(varchar型);msgid(varchar型)

Select *
From A_Table
Where add_time Between '2007-1-1' And '2007-7-1' And msgid In(Select msgid
     From B_Table
     Where stat='0')

这样的语句应当如何优化, 用 Join 查询会提高查询效率和查询时间,时间对我来说更重要.

还希望多介绍些优化查询理论和技巧.


posted @ 2007-07-06 17:27 小罗 阅读(585) | 评论 (1)编辑
SQL 2000 是服务器端, SQL 2005 是客户端.

SQL2005用的不熟.  主要不会设置SQL 2000的服务器,配置用户,权限都不太清楚, 望多指教.

posted @ 2007-07-05 13:17 小罗 阅读(341) | 评论 (6)编辑
     摘要: 找到一段程序,看到委托操作的地方不太理解,希望朋友们多多指教。特别是委托操作的执行流程或处理机制不理解。程序如下 :Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->1usingSystem;2usingSystem.Collections.Generi... 阅读全文
posted @ 2007-05-21 23:12 小罗 阅读(284) | 评论 (9)编辑
  2008年1月21日
     摘要: 前言关于ASP.NET的底层的工作机制,最近园子里讨论的甚是火热。相信很多人都看过Rick Strahl先生的一篇经典之作:A low-level Look at the ASP.NET Architecture,经Rick Strahl先生同意,我把他的这篇文章翻译成中文,希望能够给想深入了解ASP.NET工作机制的朋友一点帮助。特别说明:翻译此文的目的仅仅是为了给广大的ASP.NET爱好者提供... 阅读全文
posted @ 2008-01-21 23:08 小罗 阅读(129) | 评论 (0)编辑

据说通过HttpModules可以将类似于:http://www.infotouch.cn/detail.aspx?id=120 的URL地址重写为:http://www.infotouch.cn/detail/120.aspx 。这样最直接的好处就是可以让搜索引擎搜索到页面,因为搜索引擎对?之后的参数不太理睬。

今天尝试了一下,发现一个需要注意的问题,就是HttpModules只能对特定扩展名的URL进行重写(注:只能对“映射”-“应用程序扩展”中指定交给Asp.Net处理的扩展名文件进行处理),从Google找了些英文资料,发现这种情况是由IIS处理请求的机理决定的。

IIS对于没有扩展名的URL处理请求的机理:

如果请求的路径(path)有扩展名,IIS首先查找是否已设定了对应的应用程序扩展,有则将控制权交给该应用程序:
所以对于 http://www.infotouch.cn/detail.aspx?id=120 这样的情况很容易处理,只要处理为 http://www.infotouch.cn/detail/120.aspx 即可。因为IIS根据*.aspx的扩展名将控制权交给了Asp.Net,进而转给了HttpModules。

如果请求的路径(path)没有扩展名,例如:http://www.infotouch.cn/detail 这样的路径。IIS首先检查该虚拟路径是否对应到一个本地目录,如果具有对应的本地目录,再查找该目录下是否具有缺省文件,如果找到,就重定向为该缺省文件的路径。否则,IIS报告一个Http404-文件未找到错误。

实践:

首先写一个处理URLs重写的类,并且这个类必须继承IHttpHandler接口,以博客园的程序为例:

public class UrlReWriteModule : System.Web.IHttpModule
{
     public void Init(HttpApplication context)
     {
        context.BeginRequest +=new EventHandler(context_BeginRequest);
     }

    public void Dispose()
    {
    }
}

UrlReWriteModule类就是处理URLs重写的类,继承IHttpHandler接口,实现该接口的两个方法,Init和Dispose。在Init方法里注册自己定义的方法,如上例所示:

content.BeginRequest +=new EventHandler(content_BeginRequest);

BeginRequest是一个事件,在收到新的Http请求时触发,content_BeginRequest就是触发时处理的方法。另外说明一点,HttpModules能注册的方法还有很多,如:EndRequest、Error、Disposed、PreSendRequestContent等等。

在content_BeginRequest方法中具体处理URLs重写的细节,比如,将 http://www.cnblogs.com/archive.aspx?user=rrooyy&id=56041 重写为 http://www.cnblogs.com/rrooyy/archive/2004/10/24/56041.html 。然后将重新生成的Url用HttpContext.RewritePath()方法重写即可,如下:

private void context_BeginRequest(object sender, EventArgs e)
{
     HttpContext context   = ((HttpApplication)sender).Context;
     // 获取旧的Url
     string url = context.Request.Path.ToLower();
     // 重新生成新的Url
     string newUrl = ...; // 具体过程略
     // 重写Url
     context.RewritePath(newUrl);
}

提醒:newUrl的格式不是http://www.infotouch.com/user/archive.aspx,而是从当前应用程序根目录算起的绝对路径,如:user\archive.aspx,这一点请特别注意。

最后要web.config中注册重写URLs的类,格式如下:

<HTTPMODULES>
    <ADD type="classname,assemblyname" name="modulename"/>
    <REMOVE name="modulename"/>
    <CLEAR />
</HTTPMODULES>

采用<ADD>标签可以注册一个类;<REMOVE>可以移除某个类,如果某个子目录不希望继承父目录的某个Http Module注册,就需要使用这个标签;<CLEAR />可以移除所有的Http Module注册。

posted @ 2008-01-21 21:58 小罗 阅读(85) | 评论 (0)编辑

掌握了会话状态基本知识之后,让我们通过分析会话状态管理的技术细节,增强我们的技能。会话状态处理是一个可以用以下三个步骤概括的任务:分配一个会话ID;从一个提供程序那里获取会话数据;把它填充到页面的上下文中。如前所述,会话状态模块控制所有这些任务的执行。这样做时,它利用两个额外组件:会话ID生成器和会话状态提供程序。在ASP.NET 2.0中,这两个组件都可以用定制组件代替,后文将对此进行介绍。现在,要解决使用会话状态时面临的实际问题。

13.3.1 标识一个会话

每个活动的ASP.NET会话使用一个只由URL允许的字符组成的120位字符串进行标识。会话ID被保证是惟一的并且是随机产生的,以避免数据冲突和防止恶意攻击。根据现有ID通过算法来获得一个有效的会话ID实际上并不可行。在ASP.NET 1.x中,会话ID生成器是一个埋藏在框架中的系统组件,对外部不可见。在ASP.NET 2.0中,会话ID生成器变成了一个可定制的组件,开发人员可以有选择地替换它。

注意

一个古老的谚语提醒了我们,任何事情都不能仅仅因为可行就去做(nothing should be done only because it is doable)。这个谚语特别适合这里的情形,因为我们在讨论ASP.NET 2.0中可定制的会话状态管理。这些子系统(诸如会话ID生成器)只有在理由充分的情况下才进行定制,并且确保这么做不会使事情变得更糟或者降低安全水平。稍后我将更详细地讨论这一点。

1. 创建会话ID

根据设计,会话ID长15字节(15×8=120位)。会话ID是使用随机数生成器(Random Number Generator,简称RNG)密码提供程序生成。该服务提供程序返回一个由15个随机生成的数值组成的数组。然后把该数组映射到有效的URL字符,并作为一个字符串返回。

如果会话没有包含任何数据,则为每个请求生成一个新的会话ID,并且会话状态并不持久地存储在状态提供程序中。然而,如果使用一个 Session_Start处理程序,则会话状态总是被保存,即使它为空。由于这个原因,特别是在没有使用进程内会话提供程序时,定义 Session_Start处理程序要特别小心,并且只有在确实需要时才定义。

相反,在一个非空的会话字典超时或被丢弃之后,会话ID仍然不变。根据设计,即使会话状态到期,会话ID一直延续到浏览器会话结束为止。这就是说,只要浏览器实例保持相同,则同一个会话ID用来表示一段时间内的多个会话。

2. 会话cookie

SessionID字符串传递给浏览器,然后以如下两种方法之一返回给服务器应用程序:使用一个cookie或一个修改过的URL。在默认情况下,会话状态模块在客户端创建一个HTTP cookie,但也可以使用一个修改过的URL,其中嵌入SessionID字符串,特别针对无cookie的浏览器。具体采取哪种方法取决于应用程序的 web.config文件中存储的配置设置。在默认情况下,会话状态使用cookie。

实际上,cookie只不过是网页放在客户端硬盘上的一个文本文件。在ASP.NET中,cookie由HttpCookie类的一个实例表示。一个cookie通常有一个名称、一个值集合和一个到期时间。此外,我们可以对cookie进行配置,以通过安全连接作用于特定的虚拟路径(例如, HTTPS)。

重要提示

ASP.NET 2.0利用HTTP-only特征建立支持会话cookie的浏览器上的会话cookie。例如,在Microsoft Internet Explorer 6.0 sp1或安装了Windows XP SP2的系统上支持会话cookie。HTTP-only特征防止这些cookie被用于客户端脚本,从而竖起一道屏障,以防可能发生的旨在偷取会话ID 的跨站点脚本 攻击。

当cookie被启用时,会话状态模块实际创建一个具有特定名称的cookie,并把会话ID保存在它那里。cookie的创建如下面的伪码所示:

HttpCookie sessionCookie;

sessionCookie = new HttpCookie("ASP.NET_SessionId", sessionID);

sessionCookie.Path = "/";

ASP.NET_SessionId是cookie的名称,而sessionID字符串是它的值。cookie也与当前域的根关联。Path属性描述应用cookie的相对URL。会话cookie被给予一个非常短的到期期限,并在每个成功的请求结束时续订。cookie的Expires属性指出该 cookie在客户端到期的时间。如果没有显式地设置该属性(会话cookie通常就是这样),则Expires属性默认为 DateTime.MinValue——即.NET Framework中可能的最小时间单位。

注意

需要写入一个cookie的服务器端模块添加一个HttpCookie对象到Response.Cookies集合中。客户端存在的并与被请求领域关联的所有cookie都被上传,并使其可以通过Request.Cookies集合读取。

3. 无cookie会话

为了使会话状态起作用,客户端必须能够把会话ID传递给服务器端应用程序。这种情况如何发生依赖于应用程序的配置。ASP.NET应用程序通过配置文件的<sessionState>节定义它们的会话特有的设置。为了决定cookie支持,将cookieless属性设置为表13.7中的一个值。表中所列的值属于HttpCookieMode枚举类型。

表13.7 HttpCookieMode枚举类型

模 式

描 述

AutoDetect

只有在请求浏览器支持cookie时才使用cookie

UseCookies

使用cookie持久地存储会话ID,而不管浏览器是否支持cookie。这是默认选项

UseDeviceProfile

根据配置文件的设备配置文件节所列的浏览器能力作出决策

UseUri

将会话ID存储在URL中,不管浏览器是否支持cookie。如果在任何情况下都不使用cookie,则使用该选项

使用AutoDetect时,ASP.NET将查询浏览器以确定它是否支持cookie。如果浏览器支持cookie,会话ID就存储在一个 cookie中;否则,会话ID将存储在URL中。另一方面,使用UseDeviceProfile模式时,不检查浏览器的有效能力。为了让HTTP会话模块决定使用cookie还是URL,使用由HttpBrowserCapabilities对象的 SupportsRedirectWithCookie属性产生的浏览器所声明的功能。要注意的是,即使浏览器能够支持cookie,但是用户可能会禁用 cookie。在这种情况下,会话状态不能正确起作用。

注意

在ASP.NET 1.x中,可以选择的方案更少。<sessionState>节的cookieless属性只能接收一个布尔值。若要禁用会话中的cookie,则将该属性设置为true。

在禁用cookie支持下,假设请求如下URL处的一个页面:

http://www.contoso.com/test/sessions.aspx

在浏览器的地址栏中显示的内容略有不同,而且现在包含会话ID,如下所示:

http://www.contoso.com/test/(S(5ylg0455mrvws1uz5mmaau45))/sessions.aspx

实例化时,会话状态模块检查cookieless属性的值。如果该值为true,则请求被重定向(HTTP 302状态码)到一个修改过的虚拟URL(正好在页面名称前包含会话ID)。再次被处理时,该请求嵌入会话ID。一个专用的ISAPI筛选器 (aspnet_filter.exe组件)预处理该请求,解析URL,并在该URL融入一个会话ID时重写正确的URL。所检测到的会话ID也存储在一个称为AspFilterSessionId的额外HTTP头部,并在以后进行检索。

4. 无cookie会话的问题

无cookie会话旨在使有状态的应用程序也可以在一个不支持cookie的浏览器或者在一个没有启用cookie的浏览器上运行,但它也存在问题。首先,当会话开始时,以及每当用户从一个应用程序的页面内跟随一个绝对URL时,它们会导致重定向。

使用cookie时,我们可以清除地址栏,进入另一个应用程序,然后转向前一个应用程序,并检索相同的会话值。如果在禁用会话时这么做,会话数据会丢失。该特征对于页面回发没有什么问题,因为这是使用相对URL自动实现的,但若使用绝对URL进行链接,则会引发一个严重的问题。在这种情况下,总是会创建一个新的会话。例如,如下代码中断会话:

<a runat="server" href="/test/sessions.aspx">Click</a>

有没有一种办法自动打破链接或超链接中的绝对URL,以便它们融入会话信息吗?我们可以使用如下技巧,它使用了HttpResponse类的ApplyAppPathModifier方法:

<a href='<% =Response.ApplyAppPathModifier("test/page.aspx")%>' >Click</a>

ApplyAppPathModifier方法取一个表示相对URL的字符串,并返回一个绝对URL,其中嵌入会话信息。需要从一个HTTP页面重定向到一个HTTPS页面(其中强制要求完整的绝对地址)时,则上述技巧特别有用。要注意的是,如果会话cookie被启用,并且路径是绝对路径,则 ApplyAppPathModifier返回原始URL。

警告 在服务器端表达式(即标记了runat=server属性的表达式)中,不能使用<%...%>代码块。之所以在上述代码中可行,是因为<a>标签被逐字发出,没有设置runat属性。

5. 无cookie会话和安全性

使用无cookie会话的另一个问题与安全性有关。会话欺诈是最流行的攻击类型之一,牵涉到通过为另一个合法用户生成的会话ID访问外部系统。请尝试下面的做法:将应用程序设置为在无cookie下工作,并访问一个页面。当会话ID在浏览器的地址栏中出现时,获取它的URL,并立即通过电子邮件发给一位朋友。让你的朋友把URL粘贴到自己的机器上并单击“转到”。只要会话有效,你的朋友就能访问你的会话状态。毫无疑问,会话ID并没有得到良好的保护。为了系统的安全性,关键是有一个不可预测的ID生成器,因为它使猜测有效的会话ID更难了。对于无cookie会话,会话ID在地址栏中提供给外界,并且对所有的人都是可见的。由于这个原因,如果把专用的或机密的信息存储在会话状态中,建议使用安全套接字层(Secure Sockets Layer,SSL)或传输层安全性(Transport Layer Security,TLS)加密浏览器和服务器之间的包含会话ID的任何通信。

此外,当用户认为这么做违反了安全性时,始终应当使他们能够退出登录,并调用Abandon方法。对使用会话ID来窃取会话状态中所存储数据的人来说这种设计减少了他们的时间,而说到安全性,重要的是在使用无cookie会话时要对系统进行配置,以免重用过期的会话ID。此行为在ASP.NET中可以通过<sessionState>节进行配置,下一节将详细 介绍。

6. 配置会话状态

从ASP.NET 1.x迁移到ASP.NET 2.0以后,<sessionState>节的内容显著增多了。该节的内容如下所示:

<sessionState

mode="Off|InProc|StateServer|SQLServer|Custom"

timeout="number of minutes"

cookieName="session cookie name"

cookieless="http cookie mode"

regenerateExpiredSessionId="true|false"

sqlConnectionString="sql connection string"

sqlCommandTimeout="number of seconds"

allowCustomSqlDatabase="true|false"

useHostingIdentity="true|false"

partitionResolverType=""

sessionIDManagerType="custom session ID generator"

stateConnectionString="tcpip=server:port"

stateNetworkTimeout="number of seconds"

customProvider="custom provider name">

<providers>

...

</providers>

</sessionState>

表13.8详细描述了各个属性的目标和特征。要注意,只有mode,timeout,stateConnectionString和 sqlConnectionString属性在ASP.NET 1.x中有对等的属性。cookieless属性在ASP.NET 1.x中也存在,但是它接受布尔值。所有其他属性都是ASP.NET 2.0新引入的。

表13.8 <sessionState>属性

属 性

描 述

allowCustomSqlDatabase

如果为true,则能够指定一个定制数据库表来存储会话数据,而不必使用标准的ASPState

Cookieless

指定如何把会话ID传递给客户端

cookieName

cookie的名称(如果cookie用于会话ID的话)

customProvider

定制的会话状态存储提供程序的名称,用于存储和检索会话状态数据

mode

指定把会话状态存储在哪里

partitionResolverType

当会话状态工作于SQLServer或StateServer模式时,指明被加载以提供连接信息的分区解析器组件的类型和程序集。如果可以正确地加载分区解析器,则忽略sqlConnectionString和stateConnectionString属性

regenerateExpiredSessionId

用一个已过期的会话ID发出一个请求时,如果该属性为true,则生成一个新的会话ID;否则,重新使用过期的会话ID。默认值为false

sessionIDManagerType

默认为Null。如果设置了该属性,则指明用作会话ID的生成器的组件

sqlCommandTimeout

指定一个SQL命令在被取消前可以空闲的秒数。默认为30秒

sqlConnectionString

指定SQL Server的连接字符串

stateConnectionString

指定用来远程存储会话状态的服务器名称或地址和端口

stateNetworkTimeout

指定Web服务器和状态服务器之间的TCP/IP网络连接在请求被取消前可以空闲的秒数。默认为10秒

timeout

指定一个会话在被放弃前可以空闲的秒数。默认为20秒

useHostingIdentity

默认值为True。它指明在访问一个定制的状态提供程序或者进行了集成安全性配置的SQLServer提供程序时,ASP.NET进程标识被假冒

此外,子<providers>节列出了定制的会话状态存储提供程序。ASP.NET会话状态旨在使我们能够轻松地把用户会话数据存储在不同的源中,如Web服务器的内存中或SQL Server。存储提供程序是一个管理会话状态信息的存储并把它存储在另一种介质(例如,Oracle)或布局中的组件。我们将在本章后面重新讨论该主题。

13.3.2 会话的生命期

只有在第一个数据项添加到内存中的会话字典时,会话状态的生命才开始。如下代码说明了如何修改会话字典中的一个数据项。“MyData”是惟一地标识该值的键。如果该字典中已经存在一个称为“MyData”的键,则重写现有的值:

Session["MyData"] = "I love ASP.NET";

Session字典通常包含object类型;要读回数据,需要将返回值转换为一种更具体的 类型:

string tmp = (string) Session["MyData"];

当页面把数据保存到Session字典中时,返回值被加载到一个内存中的字典——即,SessionDictionary内部类的一个实例(参见图13.2)。其他并发运行的页面不能访问该会话,直到正在进行的请求完成为止。

1. Session_Start事件

会话启动事件与会话状态无关。当会话状态模块服务给定用户发出的要求新会话ID的第一个请求时,Session_Start事件激发。ASP.NET运行库可以在一个会话上下文中服务多个请求,但是只对它们中的第一个请求激发Session_Start事件。

每当请求一个不把数据写入会话字典中的页面时,创建一个新的会话ID,并激发一个新的Session_Start事件。会话状态的体系结构非常复杂,因为它必须支持各种状态提供程序。总体方案要求在请求完成时把会话字典的内容序列化到状态提供程序。然而,为了优化性能,只有在字典的内容不空时该过程才会真正执行。然而,如前所述,如果应用程序定义了一个Session_Start事件处理程序,则无论如何都会发生序列化。

2. Session_End事件

Session_End事件表示会话的结束,用来执行终止会话所需的任何清除代码。然而要注意的是,只有在Inproc模式下,即当会话数据存储在ASP.NET工作进程中时,才支持该 事件。

为了使Session_End事件激发,会话状态必须先存在。这就是说,我们必须把一些数据存储在会话状态中,并且至少必须完成一个请求。第一个值添加到会话字典中时,一个数据项插入ASP.NET缓存——上述的Cache对象将在下一章详细介绍。该行为是进程中的状态提供程序所特有的;进程外状态提供程序和SQL Server状态服务器都不使用Cache 对象。

然而,更有趣的是,添加到缓存中的数据项(每个活动会话只有一个数据项)被赋予一个特殊的到期策略。我们将在下一章学习ASP.NET缓存及其相关的到期策略。而现在,只要知道添加到该缓存中的会话状态项被赋予一个活动到期时间,其间隔时间设置为会话超时时间。只要在会话内还有请求要处理,则滑动到期期限自动续订。会话状态模块在处理EndRequest事件时重置超时时间。只要通过对缓存执行一次读取操作,它就能获得期望的结果!给定 ASP.NET Cache对象的内部结构,这就等于续订滑动到期期限。因而,当缓存项到期时,该会话已经超时。

到期的缓存项自动地从缓存中删除。作为该项的到期策略的一部分,状态会话模块还指示一个删除回调函数。缓存自动地调用该删除方法,而后者激发Session_End事件。

注意

Cache中表示一个会话的状态的数据项,不能从system.web程序集的外部进行访问,更不能进行列举,因为它们被存放在一个系统保留的缓存区域。换句话说,我们不能以编程的方式访问驻留在另一个会话中的数据,更不能删除它。

3. 为什么我的会话状态会丢失?

当会话超时或被放弃时,Session对象中存储的值要么以编程的方式从内存中删掉,要么被系统从内存中删掉。然而,在某些情况下,会话状态会不知不觉地丢失。如何解释这种奇怪的行为呢?

当工作模型是InProc时,会话状态在正在服务该页面请求的AppDomain的内存空间中被映射。根据该规定,会话状态受进程回收和 AppDomain重启支配。ASP.NET工作进程定期重启,以维护良好的平均性能;当ASP.NET工作进程重启时,会话状态丢失。进程回收取决于内存消耗百分比,还有可能取决于被服务的请求量。虽然这是周期性的,但是不能对周期的间隔时间做出一般的估计。在设计基于会话的、进程内应用程序时,要注意这一点。通常要记住的是,试图访问会话状态,它可能没有。尽量使用适合自己的应用程序的异常处理或还原技术。

考虑到一些反病毒软件可能把web.config或Global.asax文件标记为已修改,导致一个新的应用程序启动,从而丢失会话状态。如果我们或我们的代码修改那些文件的时间戳,或者修改其中一个专用文件夹(诸如Bin或App_Code等)的内容,也会丢失会话状态。

注意

当一个正在运行的页面碰到一个错误时,会话状态会发生什么呢?在请求结束时,如果页面产生一个错误——即,Server对象的 GetLastError方法返回一个异常,则该会话的状态不会被保存。然而,如果在异常处理程序中通过调用Server.ClearError重置错误状态,则好像没有发生任何错误一样有规律地保存会话的值。
posted @ 2008-01-21 15:56 小罗 阅读(124) | 评论 (1)编辑
  2008年1月19日
技巧 os javascript html asp.net
  
    通过ASP.NET可以对一些无用的进程进行远程杀死,下面的代码先列出正在活动的所有进程,然后进行杀死。需要注意的是:这个文件要放在具有Administrator访问权限的虚拟目录下。
    
    以下是C#代码:
    <%@ Page Language="c#" %>
    <HTML>
  
    <HEAD>
    <% @ Import namespace= "System.Diagnostics" %>
    <script language="C#" runat="Server" debug="true">
    void Page_Load(Object Sender, EventArgs e){
    btnKill.Attributes.Add("onclick", "javascript: return confirm('你真的要杀死这个进程吗?');");
    }
    
    private void KillProcess(string processName){
    System.Diagnostics.Process myproc= new System.Diagnostics.Process();
    //得到所有打开的进程
    try{
    foreach (Process thisproc in Process.GetProcessesByName(processName)) {
    if(!thisproc.CloseMainWindow()){
    thisproc.Kill();
    }
    }
    }
    catch(Exception Exc)
    {
    msg.Text+= "杀死" +procname.SelectedItem.Text + "失败!";
    }
    }
    public void btnKill_Click(object sender, System.EventArgs e)
    {
    KillProcess(procname.SelectedItem.Text);
    msg.Text= procname.SelectedItem.Text +" 已经被杀死。";
    }
    
    
    public void btnShow_Click(object sender, System.EventArgs e){
    ArrayList procList =new ArrayList();
    string tempName="";
    int begpos;
    int endpos;
    foreach (Process thisProc in System.Diagnostics.Process.GetProcesses()) {
    tempName=thisProc.ToString();
    begpos = tempName.IndexOf("(")+1;
    endpos= tempName.IndexOf(")");
    tempName=tempName.Substring(begpos,endpos-begpos);
    procList.Add(tempName);
    }
    procname.DataSource=procList;
    procname.DataBind();
    }
    </script>
    </HEAD>
    <body>
    <Basefont Face="Tahoma" />
    <center><h2>ASP.NET 进程杀死器!</h2>
  
    <Table cellspacing=2 cellpadding=2 border=0 BGCOLOR="#fFCC66">
    <form id="frmProc" runat="Server" method="post">
    <TR><TD><ASP:DropDownList id="procname" runat="server" /></TD><TD>
    进程名字</TD></TR>
    <TR><TD>
    <asp:button id="btnKill" Text="杀死进程" runat="server" CausesValidation="False" onclick="btnKill_Click" />
    </TD>
    <TD><asp:button id="btnShow" Text="列出所有进程" runat="server" CausesValidation="False" onclick="btnShow_Click" />
    </TD></TR>
    </TABLE>
    <center><asp:Label id="msg" runat="server"/></center>
    </form>
    </center>
    </body>
    </HTML>
posted @ 2008-01-19 16:44 小罗 阅读(65) | 评论 (0)编辑
关于Forms验证的文章网上千百篇,但我花了1天半的时间学会了“一点点”,
  现在把代码分享出来,希望对像我一样的初学者所有帮助,也希望高手给指点一下:
  
  --------------------------------------------------------------------------------
  
  Step 1:新建数据库(库:MyForms ;表:users ;字段:ID,userName, userPwd);
  Step 2:新建网站,web.config 的文件全部代码如下:
  
  
  web.config 的全部代码
  <?xml version="1.0"?>
  <configuration>
   <appSettings/>
   <connectionStrings/>
  
   <system.web>
   <compilation debug="true"/>
  
   <sessionState cookieless="AutoDetect"/>
   <!--解决当浏览器端禁用Cookie时-->
  
   <authentication mode="Forms">
   <forms name="CookieName" loginUrl="login.aspx" protection="All"></forms>
   <!--loginUrl为登录面URL,如果没有身份验证Cookie,客户端将被重定向到此URL-->
   </authentication>
  
   <authorization>
   <deny users="?"/>
   </authorization>
  
   <customErrors mode="On" defaultRedirect="GenericErrorPage.htm">
   <error statusCode="403" redirect="NoAccess.htm" />
   <error statusCode="404" redirect="FileNotFound.htm" />
   </customErrors>
  
   </system.web>
  
  </configuration>
  
  Step 3:添加一个 login.aspx 页面;拖2个 TextBox ,1个Button 和1个CheckBox ;
   并将CheckBox 的text 属性设为:“是否保存Cookis ";
  Step 4:login.aspx 的隐藏代码如下:
  
  login 全部隐藏代码
  using System;
  using System.Data;
  using System.Configuration;
  using System.Web;
  using System.Web.Security;
  using System.Web.UI;
  using System.Web.UI.WebControls;
  using System.Web.UI.WebControls.WebParts;
  using System.Web.UI.HtmlControls;
  using System.Data.SqlClient; //导入命名空间
  
  public partial class _Default : System.Web.UI.Page
  {
   protected void Page_Load(object sender, EventArgs e)
   {
  
   }
   protected void Button1_Click(object sender, EventArgs e)
   {
   string userName = TextBox1.Text.Trim();
   string userPwd = TextBox2.Text.Trim();
   SqlConnection con = new SqlConnection("Server=.;Database=MyForms;User ID=sa;Password=123456");
   con.Open();
   SqlCommand cmd = new SqlCommand("select count(*) from users where userName='" + userName + "' and userPwd='" + userPwd + "'", con);
   int count = Convert.ToInt32(cmd.ExecuteScalar());
   if (count > 0)
   {
   System.Web.Security.FormsAuthentication.SetAuthCookie(this.TextBox1.Text, this.CheckBox1.Checked);
   Response.Redirect("Default.aspx");
   //上面两行,也可以换成下面一行,如通过验证则直接转向请求的页面,而不需要Responsel.Redirect("");
   //System.Web.Security.FormsAuthentication.RedirectFromLoginPage(this.TextBox1.Text, false);
   }
  
   else
   {
   Response.Write("用户不合法");
   }
   }
  }
  
  Step 5:拖一个Button 到 Default.aspx 上,将其text 属性设为"登出",其事件代码如下:
  
  Button 事件代码
  protected void Button1_Click(object sender, EventArgs e)
   {
   System.Web.Security.FormsAuthentication.SignOut();
   }
posted @ 2008-01-19 16:03 小罗 阅读(69) | 评论 (0)编辑
SQL Server提供了一个特别的数据类型:image,它是一个包含binary数据的类型。下边这个例子就向你展示了如何将文本或照片放入到数据库中的办法。在这篇文章中我们要看到如何在SQL Server中存储和读取图片。
  
    1、建立一个表:
  
    在SQL SERVER中建立这样结构的一个表: 
   
    2、存储图片到SQL SERVER数据库中
  
    为了能存储到表中,你首先要上传它们到你的WEB 服务器上,你可以开发一个web form,它用来将客户端中TextBox web control中的图片入到你的WEB服务器上来。将你的 encType 属性设置为:myltipart/formdata.
  
    Stream imgdatastream = File1.PostedFile.InputStream;
  
    int imgdatalen = File1.PostedFile.ContentLength;
  
    string imgtype = File1.PostedFile.ContentType;
  
    string imgtitle = TextBox1.Text;
  
    byte[] imgdata = new byte[imgdatalen];
  
    int n = imgdatastream.Read(imgdata,0,imgdatalen);
  
    string connstr=((NameValueCollection)Context.GetConfig("appSettings"))["connstr"];
  
    SqlConnection connection = new SqlConnection(connstr);
  
    SqlCommand command = new SqlCommand
  
    ("Insert INTO ImageStore(imgtitle,imgtype,imgdata)
  
    VALUES ( @imgtitle, @imgtype,@imgdata )", connection );
  
    SqlParameter paramTitle = new SqlParameter
  
    ("@imgtitle", SqlDbType.VarChar,50 );
  
    paramTitle.Value = imgtitle;
  
    command.Parameters.Add( paramTitle);
  
    SqlParameter paramData = new SqlParameter( "@imgdata", SqlDbType.Image );
  
    paramData.Value = imgdata;
  
    command.Parameters.Add( paramData );
  
    SqlParameter paramType = new SqlParameter( "@imgtype", SqlDbType.VarChar,50 );
  
    paramType.Value = imgtype;
  
    command.Parameters.Add( paramType );
  
    connection.Open();
  
    int numRowsAffected = command.ExecuteNonQuery();
  
    connection.Close();
  
    3、从数据库中恢复读取
  
    现在让我们来从SQL Server中读取我们放入的数据吧!我们将要输出图片到你的浏览器上,你也可以将它存放到你要的位置。
  
    private void Page_Load(object sender, System.EventArgs e)
  
    {
  
    string imgid =Request.QueryString["imgid"];
  
    string connstr=((NameValueCollection)
  
    Context.GetConfig("appSettings"))["connstr"];
  
    string sql="Select imgdata, imgtype FROM ImageStore Where id = " + imgid;
  
    SqlConnection connection = new SqlConnection(connstr);
  
    SqlCommand command = new SqlCommand(sql, connection);
  
    connection.Open();
  
    SqlDataReader dr = command.ExecuteReader();
  
    if(dr.Read())
  
    {
  
    Response.ContentType = dr["imgtype"].ToString();
  
    Response.BinaryWrite( (byte[]) dr["imgdata"] );
  
    }
  
    connection.Close();
  
    }
  
    要注意的是Response.BinaryWrite 而不是Response.Write.
  
    下面给大家一个用于C# Winform的存入、读取程序。其中不同请大家自己比较!(为了方便起见,我将数据库字段简化为二个:imgtitle和imgdata。
  
    using System;
  
    using System.Drawing;
  
    using System.Collections;
  
    using System.ComponentModel;
  
    using System.Windows.Forms;
  
    using System.Data;
  
    using System.IO;
  
    using System.Data.SqlClient;
  
    namespace WindowsApplication21
  
    {
  
    ///
  
    /// Form1 的摘要说明。
  
    ///
  
    public class Form1 : System.Windows.Forms.Form
  
    {
  
    private System.Windows.Forms.Button button1;
  
    ///
  
    /// 必需的设计器变量。
  
    ///
  
    private System.ComponentModel.Container components = null;
  
    private string ConnectionString = "Integrated Security=SSPI;Initial Catalog=;DataSource=localhost;";
  
    private SqlConnection conn = null;
  
    private SqlCommand cmd = null;
  
    private System.Windows.Forms.Button button2;
  
    private System.Windows.Forms.PictureBox pic1;
  
    private System.Windows.Forms.OpenFileDialog openFileDialog1;
  
    private string sql = null;
  
    private System.Windows.Forms.Label label2;
  
    private string nowId=null;
  
    public Form1()
  
    {
  
    //
  
    // Windows 窗体设计器支持所必需的
  
    //
  
    InitializeComponent();
  
    conn = new SqlConnection(ConnectionString);
  
    //
  
    // TODO: 在 InitializeComponent 调用后添加任何构造函数代码
  
    //
  
    }
  
    ///
  
    /// 清理所有正在使用的资源。
  
    ///
  
    protected override void Dispose( bool disposing )
  
    {
  
    if (conn.State == ConnectionState.Open)
  
    conn.Close();
  
    if( disposing )
  
    {
  
    if (components != null)
  
    {
  
    components.Dispose();
  
    }
  
    }
  
    base.Dispose( disposing );
  
    }
  
    #region Windows Form Designer generated code
  
    ///
  
    /// 设计器支持所需的方法 - 不要使用代码编辑器修改
  
    /// 此方法的内容。
  
    ///
  
    private void InitializeComponent()
  
    {
  
    this.button1 = new System.Windows.Forms.Button();
  
    this.pic1 = new System.Windows.Forms.PictureBox();
  
    this.button2 = new System.Windows.Forms.Button();
  
    this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
  
    this.label2 = new System.Windows.Forms.Label();
  
    this.SuspendLayout();
  
    //
  
    // button1
  
    //
  
    this.button1.Location = new System.Drawing.Point(0, 40);
  
    this.button1.Name = "button1";
  
    this.button1.Size = new System.Drawing.Size(264, 48);
  
    this.button1.TabIndex = 0;
  
    this.button1.Text = "加入新的图片";
  
    this.button1.Click += new System.EventHandler(this.button1_Click);
  
    //
  
    // pic1
  
    //
  
    this.pic1.Location = new System.Drawing.Point(280, 8);
  
    this.pic1.Name = "pic1";
  
    this.pic1.Size = new System.Drawing.Size(344, 264);
  
    this.pic1.TabIndex = 3;
  
    this.pic1.TabStop = false;
  
    //
  
    // button2
  
    //
  
    this.button2.Location = new System.Drawing.Point(0, 104);
  
    this.button2.Name = "button2";
  
    this.button2.Size = new System.Drawing.Size(264, 40);
  
    this.button2.TabIndex = 4;
  
    this.button2.Text = "从数据库中恢复图像";
  
    this.button2.Click += new System.EventHandler(this.button2_Click);
  
    //
  
    // openFileDialog1
  
    //
  
    this.openFileDialog1.Filter = ""图像文件(*.jpg,*.bmp,*.gif)|*.jpg|*.bmp|*.gif"";
  
    //
  
    // label2
  
    //
  
    this.label2.Location = new System.Drawing.Point(0, 152);
  
    this.label2.Name = "label2";
  
    this.label2.Size = new System.Drawing.Size(264, 48);
  
    this.label2.TabIndex = 5;
  
    //
  
    // Form1
  
    //
  
    this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
  
    this.ClientSize = new System.Drawing.Size(632, 273);
  
    this.Controls.AddRange(new System.Windows.Forms.Control[] {
  
    this.label2,
  
    this.button2,
  
    this.pic1,
  
    this.button1});
  
    this.Name = "Form1";
  
    this.Text = "Form1";
  
    this.Load += new System.EventHandler(this.Form1_Load);
  
    this.ResumeLayout(false);
  
    }
  
    #endregion
  
    ///
  
    /// 应用程序的主入口点。
  
    ///
  
    [STAThread]
  
    static void Main()
  
    {
  
    Application.Run(new Form1());
  
    }
  
    private void button1_Click(object sender, System.EventArgs e)
posted @ 2008-01-19 16:00 小罗 阅读(118) | 评论 (0)编辑
一、 错误(以外)的处理
  程序健壮性最基本要求就是程序错误的处理与捕捉,在ASP.NET中,错误的处理有和其他编程语言一样的机制,可以使用Try…Catch…Finally等方式,这一点和ASP相比具有较大的进步。而且,使用这些错误处理方法,可以大大提高程序的可读性和程序调试速度,在这几个优势结合的情况下,我们更加应该注意这一点。
  关于错误的处理,我们可以参考这篇文章(英文):
  http://www.123aspx.com/redir.aspx?res=28336
  
  二、 字符串的处理
  网页设计中,字符串的处理几乎是最常见的了。使用ASP.NET以后,字符串的处理比ASP的速度快,而且,在ASP.NET中,专门增加一个字符串处理类StringBulider,使用这个类可以完成一些常见的字符串操作,而最主要的,使用StringBuilder可以大大提高字符串处理速度。
  在ASP.NET中,最常见的就是使用“&”来连接两个字符串:
  Dim myOutputString As String = "My name is"
  Dim myInputString As String = " Alex"
  myOutputString = myOutputString & myInputString
  Response.Write(myoutputString)
  现在,我们来看看StringBuilder的使用,在使用StringBuilder的时候,我们对字符串可以做一些基本的操作,比如Append、Replace、Insert、Remove等,现在我们来看具体举例。
  (1)StringBuilder中Append的使用
  Append和其他语言的Append一样,就是在字符串最后增加其他字符。
  Dim sb as StringBuilder = New StringBuilder()
  sb.append( "<table border='1' width='80%'>" )
  For i = 0 To RowCount - 1
  sb.Append("<tr>")
  For k = 0 To ColCount - 1
  sb.Append("<td>")
  sb.Append( dt.Rows(i).Item(k, DataRowVersion.Current).toString())
  sb.Append( "</td>" )
  Next
  sb.Append("<tr>")
  Next
  sb.Append( "</table>")
  Dim strOutput as String = sb.ToString()
  lblCompany.Text = strOutput
  在以上的程序中,用Append方法实现了一个表格的输出,需要注意的一点是,StringBulider必须首先使用ToString()方法将其转化为String类型才可以直接输出。在以上的举例中,我们看到的全部是Append一个直接的字符串,其实,这个方法有一个很方便的功能,那就是可以直接Append其他类型的变量,比如可以直接Appemd一个Integer类型的数值,当然,我们输出以后自动转化为一个字符串:
  Sub Page_Load(Source As object, E As EventArgs)
  Dim sb As System.Text.StringBuilder
  Dim varother As Integer
  varother=9999
  sb =new System.Text.StringBuilder()
  sb.append("<font color='blue'>可以Append其他类型:</font>")
  sb.append(varother)
  Response.write(sb.toString())
  End Sub
  (2)字符串中其他方法的使用
  我们还可以使用其他方法,我们来看看常见的:
  Insert方法,可以在指定位置插入其他字符,使用方法:Insert(插入位置,插入字符);
  Remove方法,可以在指定位置删除指定字数字符,使用方法:Remove(其实位置,字符数);
  Replace方法,可以替换指定字符,使用方法:replace(被替换字符串,替换字符串)
  字符串的具体介绍和使用方法可以参考以下文章(英文):
  http://aspfree.com/aspnet/stringbuilder.aspx
  http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemTextStringBuilderClassTopic.asp
  
  
  
  三、 数据库链接Connection和DataReader的关闭
  在使用ASP编程的时候,我们就已经知道,在使用数据库连接以后,一定要将连接关闭,然后设置为NoThing。在Asp.NET中,我们仍然需要这样使用,不过,在ASP.NET中,由于使用了ADO.NET,所以,在一些相关的处理方面,实际还是有一些细微的区别,而这些区别,往往也就是我们设计的时候最需要注意的。现在,我们通过举例,来看看在常见的ADO.NET操作中,需要注意哪些问题。
  (1)举例一
  Dim myConnection As SqlConnection = new SqlConnection(ConfigurationSettings.AppSettings("DSN_pubs"))
  Dim myCommand As SqlCommand = new SqlCommand("Select pub_id, pub_name From publishers", myConnection)
  Dim myDataReader As SqlDataReader
  Try
  myConnection.Open()
  myDataReader = myCommand.ExecuteReader(CommandBehavior.CloseConnection)
  dropDownList1.DataSource = myDataReader
  dropDownList1.DataBind()
  Catch myException As Exception
  Response.Write("An error has occurred: " & myException.ToString())
  Finally
  If Not myDataReader Is Nothing Then
  '关闭DataReader
  myDataReader.Close()
  End If
  End Try
  在以上的举例中,我们注意到,这里只关闭了DataReader,并没有关闭Connection。为什么呢?仔细观察以上的ExecuteReader方法,原来,设置了ExecuteReader参数,当执行完ExecuteReader以后,会自动关闭Connection。所以,这样设置以后,就没有必要再手动关闭Connection了。
  (2)举例二
  Dim myConnection As SqlConnection = new SqlConnection(ConfigurationSettings.AppSettings("DSN_pubs"))
  Dim myCommand As SqlCommand = new SqlCommand("Select pub_id, pub_name From publishers", myConnection)
  Try
  myConnection.Open()
  dropDownList1.DataSource = myCommand.ExecuteReader()
  dropDownList1.DataBind()
  Catch myException As Exception
  Response.Write("An error has occurred: " & myException.ToString())
  Finally
  If Not myConnection Is Nothing AndAlso ((myConnection.State And ConnectionState.Open) = ConnectionState.Open) Then
  myConnection.Close()
  End If
  End Try
  在以上的举例中,我们发现,居然没有关闭DataReader。为什么呢?其实上面的代码中,没有直接生成DataReader对象,当然也就无从关闭了。需要注意一点的是,在关闭Connection之前,程序首先判断Connection是否已经打开,如果没有打开,也就没必要关闭了。
  
  
  
  
  
  四、使用Web.Config/Maching.Config保存常用数据
  一些数据我们需要时常使用,比如使用ADO.NET的时候,最常见的就是数据库连接语句,在ASP中,我们常常将这些信息保存在Application中。当然,在ASP.NET中,也可以这样,不过,ASP.NET已经提供一个配置文件WEB.Config,所以,我们最好将这些信息保存在WEB.Config中,当然,我们也可以保存在Machine.Config中,不过,这样的话,整个网站都必须使用,所以,一般我们都使用Web.Config。现在,我们来看具体这个文件的使用。
  (1)Web.Config文件的设置
  首先,我们来看Web.Config的设置,我们在这个文件中增加设置以下两个项目,设置如下:
  <configuration>
  <appsettings>
  <add key="dsn" value="myserver"/>
  <add key="someotherkey" value="somevalue"/>
  </appsettings>
  </configuration>
  (2)变量的使用
  以上XML文件设置了dsn和someotherkey两个变量,现在我们看看程序中怎样使用:
  <html>
  <script language="VB" runat=server>
  Sub Page_Load(Sender as object, E as EventArgs)
  Dim AppSettings as Hashtable = Context.GetConfig("appsettings")
  DSN.Text = AppSettings("dsn")
  SomeOther.Text = AppSettings("someotherkey")
  End Sub
  </script>
  <body>
  DSN Setting: <asp:label id="DSN" runat=server/> <br>
  Some Other Setting: <asp:label id="SomeOther" runat=server/>
  </body>
  </html>
  上面的程序我们看到,使用这样定义的变量很简单也很方便。
  
  
  五、使用.NET的方式调试程序
  ASP程序的调试一直是编写ASP最难的地方,这一点,ASP程序员大概都深有体会,因为大家都是使用Response.write来调试。而这样调试最大的缺点是,当我们调试完毕,必须一个个来删除或者注释掉这些信息,想一想,如果程序代码达到几百行或者页面很多的程序,这样的工作是多么枯燥,最怕一点,忘记将这些调试用的write删除,可能在用户使用的时候就会出现一些不雅的调试信息。
  使用ASP.NET以后,我们可以直接定义Trace来实现程序的调试。以上提到的麻烦可以轻松解决,熟悉,Trace可以通过具体页面和在Web.Config配置文件中来定义实现,这样,当程序调试完毕以后,直接将Trace设置为Off就可以了,这样,程序就不会有调试功能了。
  (1)页面调试的实现
  在一个具体的页面需要实现调试功能的时候,我们可以这样设置:
  <%@ Page Language="VB" Trace="True" %>
  (2)定义WEB.Config实现
  在WEB.CONFIG中,我们也可以实现程序调试的打开:
  <configuration>
  <system.web>
  <trace enabled="true" requestLimit="10" localOnly="false"/>
  </system.web>
  </configuration>
  使用以上的设置打开Trace以后,我们在具体的程序中就可以使用Trace来调试程序了,比如:
  Trace.Write("This is some custom debugging information")
  或者调试程序变量:
  Trace.Write("This is is my variable and it's value is:" & myVariable.ToString())
  以上设置我们可以看出,在ASP.NET中,程序调试功能已经很方便简单了
posted @ 2008-01-19 15:50 小罗 阅读(58) | 评论 (0)编辑
上次做了个项目,涉及到数据库的还原和恢复,到网上找了一下,是利用SQLDMO实现的,只要添加SQLDMO引用就好了,然后利用下边的类的方法就可以实现了。
  
   我把原作者的类扩充了一下,可以自动识别web.config里 的数据库连接字符串,可以通过变量设置还原恢复的信息。
  
  
  
   需要注意的时还原,还原的时候问题最大了,有别的用户使用数据库的时候无法还原,解决办法就是在MASTER数据库中添加一个存储过程:
  
  
  create proc killspid (@dbname varchar(20))
  as
  begin
  declare @sql nvarchar(500)
  declare @spid int
  set @sql='declare getspid cursor for
  select spid from sysprocesses where dbid=db_id('''+@dbname+''')'
  exec (@sql)
  open getspid
  fetch next from getspid into @spid
  while @@fetch_status<>-1
  begin
  exec('kill '+@spid)
  fetch next from getspid into @spid
  end
  close getspid
  deallocate getspid
  end
  GO
  
  
  在还原之前先执行这个存储过程,需要传递dbname,就是你的数据库的名字。下边是类的原代码:(web.config里的数据库连接字符串是constr)
  
  using System;
  
  using System.Configuration;
  
  using System.Data.SqlClient;
  
  using System.Data;
  
  namespace web.base_class
  
  {
  
   /// <summary>
  
   /// DbOper类,主要应用SQLDMO实现对Microsoft SQL Server数据库的备份和恢复
  
   /// </summary>
  
   public class DbOper
  
   {
  
   private string server;
  
   private string uid;
  
   private string pwd;
  
   private string database;
  
   private string conn;
  
   /// <summary>
  
   /// DbOper类的构造函数
  
   /// </summary>
  
   public DbOper()
  
   {
  
   conn=System.Configuration.ConfigurationSettings.AppSettings["constr"].ToString();
  
   server=cut(conn,"server=",";");
  
   uid=cut(conn,"uid=",";");
  
   pwd=cut(conn,"pwd=",";");
  
   database=cut(conn,"database=",";");
  
   }
  
   public string cut(string str,string bg,string ed)
  
   {
  
   string sub;
  
   sub=str.Substring(str.IndexOf(bg)+bg.Length);
  
   sub=sub.Substring(0,sub.IndexOf(";"));
  
   return sub;
  
   }
  
  
  
   /// <summary>
  
   /// 数据库备份
  
   /// </summary>
  
   public bool DbBackup(string url)
  
   {
  
   SQLDMO.Backup oBackup = new SQLDMO.BackupClass();
  
   SQLDMO.SQLServer oSQLServer = new SQLDMO.SQLServerClass();
  
   try
  
   {
  
   oSQLServer.LoginSecure = false;
  
   oSQLServer.Connect(server,uid, pwd);
  
   oBackup.Action = SQLDMO.SQLDMO_BACKUP_TYPE.SQLDMOBackup_Database;
  
   oBackup.Database = database;
  
   oBackup.Files = url;//"d:\Northwind.bak";
  
   oBackup.BackupSetName = database;
  
   oBackup.BackupSetDescription = "数据库备份";
  
   oBackup.Initialize = true;
  
   oBackup.SQLBackup(oSQLServer);
  
   return true;
  
   }
  
   catch
  
   {
  
   return false;
  
   throw;
  
   }
  
   finally
  
   {
  
   oSQLServer.DisConnect();
  
   }
  
   }
  
  
  
   /// <summary>
  
   /// 数据库恢复
  
   /// </summary>
  
   public string DbRestore(string url)
  
   {
  
   if(exepro()!=true)//执行存储过程
  
   {
  
   return "操作失败";
  
   }
  
   else
  
   {
  
   SQLDMO.Restore orestore = new SQLDMO.RestoreClass();
  
   SQLDMO.SQLServer oSQLServer = new SQLDMO.SQLServerClass();
  
   try
  
   {
  
   oSQLServer.LoginSecure = false;
  
   oSQLServer.Connect(server, uid, pwd);
  
   orestore.Action = SQLDMO.SQLDMO_RESTORE_TYPE.SQLDMORestore_Database;
  
   orestore.Database = database;
  
   orestore.Files = url;//@"d:\Northwind.bak";
  
   orestore.FileNumber = 1;
  
   orestore.ReplaceDatabase = true;
  
   orestore.SQLRestore(oSQLServer);
  
   return "ok";
  
   }
  
   catch(Exception e)
  
   {
  
   return "恢复数据库失败";
  
   throw;
  
   }
  
   finally
  
   {
  
   oSQLServer.DisConnect();
  
   }
  
   }
  
   }
  
   private bool exepro()
  
   {
  
   SqlConnection conn1 = new SqlConnection("server="+server+";uid="+uid+";pwd="+pwd+";database=master");
  
   SqlCommand cmd = new SqlCommand("killspid",conn1);
  
   cmd.CommandType = CommandType.StoredProcedure;
  
   cmd.Parameters.Add("@dbname","port");
  
   try
  
   {
  
   conn1.Open();
  
   cmd.ExecuteNonQuery();
  
   return true;
  
   }
  
   catch(Exception ex)
  
   {
  
   return false;
  
   }
  
   finally
  
   {
  
   conn1.Close();
  
   }
  
  
  
   }
  
   }
  
  }
posted @ 2008-01-19 15:48 小罗 阅读(49) | 评论 (0)编辑
在一个ASP.NET移动页面中使用DeviceSpecific/Choice构造时,你必须定义设备筛选器来测试 MobileCapabilities对象的属性。你可以在应用程序的Web.Config文件的<deviceFilters>节点中定义设备筛选器, 其中每个<filter>元素就是一个设备筛选器。下面是定义设备筛选器的语法:
  
  
  <system.web>
  <deviceFilters>
  <filter
  name="filterName"
  compare="capabilityName"
  argument="comparisonString"/>
  <filter
  name="filterName"
  type="className"
  method="methodName"/>
  </deviceFilters>
  </system.web>
  
     如上述代码所示,存在两个<filter>元素。它分别代表两种不同类型的筛选器,分别为基于比较的筛选器和基于鉴别委托的筛选器。语法指定了这两种筛 选器类型。第一种称为基于比较的筛选器,可在运行时将开发人员指定的值与设备功能的当前值进行比较。当希望确定设备是否支持某特定功能时,可使用此类筛选 器。它的各个属性为:
  
  属性 说明
  name 必需的String属性,指定设备筛选器的名称。注意,在设置该属性时要注意它是区分大小写的。例如,isHTML和IsHTML代表不同的设备筛选器。
  compare 它包含设备筛选器计算的属性。
  argument 指定该功能应与之比较的参数。如果未提供任何参数,则将 null 用于比较。
  
     下面来定义一个简单的基于比较的筛选器,你完全可以在一个<deviceFilters>元素中定义基于比较的筛选器,而无需额外的代码。例如,我们可 以添加一个用来测试某个移动设备是否支持HTML 3.2的设备筛选器,你仅需在Web.Config配置文件中添加如下的代码:
  
  <system.web>
  <deviceFilters>
  <filter name="isHTML32" compare="PreferredRenderingType" argument="html32">
  </filter>
  </deviceFilters>
  </system.web>
  
     上面的代码定义了一个名为isHTML32的筛选器,它用来测试MobileCapabilities对象的 PreferredRenderingType属性是否等于html32。除了在DeviceSpecific/Choice构造中使用上面的筛选器外, 你还可以通过使用MobileCapabilities对象的HasCapability方法来评估设备功能,此方法供ASP.NET内部使用,用来实现 用控件语法表达的各种设备选择条件。如下面的代码所示,它也是用来查看该移动设备是否支持HTML3.2标记语言,如果设备具有指定的功能,则返回值为 true,否则为false。注意,如果是基于比较的筛选器,HasCapability方法的第二个参数为null。
  
  MobileCapablities cap = (MobileCapabilities)Request.Browser;
  if ((cap.HasCapability ("isHTML32", null))
  {
  // Do something.
  }
  
    提 示:当你使用Visual Studio创建一个ASP.NET Web移动应用程序时,在添加的移动Web.Config配置文件中将包含大量的基于比较的筛选器。这些筛选器包括isWML11、isHTML32、 isCHTML10。你可以打开该配置文件,查看所有的可用设备筛选器。
  
  第二类设备筛选器称为基于鉴别委托的筛选器。当需要比基于比较的筛选器更为复杂的设备筛选功能时,可以通过提供方法的类名称和方法名称,指定基于鉴别委托的筛选器。在运行时,调用提供的方法来确定设备筛选器的计算结果是否为true。该筛选器的属性为:
  
  
  属性 说明
  name 筛选器的名称
  type 它是提供鉴别委托的类类型。名称必须符合指定完全限定类型名的Microsoft .NET标准。ASP.NET在指定的程序集中搜索该类型。
  method 它是类type上方法的名称,该方法根据传递给它的MobileCapabilities实例返回一个布尔值指示当前的设备是否满足此筛选器。
  
     现在我们来定义一个基于鉴别委托的筛选器,首先我们需要创建一个类库项目,编写和该筛选器相关的类及方法,经过编译后,再在ASP.NET Web移动应用程序中引用包含该类的程序集,具体的实现将在后面用实例进行详细的介绍。下面是类中的静态方法的具体形式(第二个参数是可选的,你可以将该 参数作为额外的输入信息添加到上面的静态方法中):
  
  public static bool MethodName
  (System.Web.Mobile.MobileCapabilities capabilities, String param)
  
     在Web.Config配置文件中,你可以采用<filter>元素的第二种形式定义基于鉴别委托的筛选器。例如,你创建了一个名为 isMMEonSony的筛选器,该筛选器使用了MyClass类中的一个名为MMEandSony的静态方法,而且该类的命名空间是 MyEvaluators.dll程序集里的MyNameSpace。因此我们需要在移动Web.Config配置文件中编写如下的代码:
  
  <system.web>
  <deviceFilters>
  <filter name="isMMEonSony"
  type="MyNameSpace.MyClass, MyEvaluators.dll"
  method="MMEandSony">
  </filter>
  </deviceFilters>
  </system.web>
  
    在上述配置中我们设置type属性为该类的完整名称:命名空间.类名,程序集。而method属性的属性值为运行时调用的实际的方法名。
  
    在DeviceSpecific/Choice构造中使用一个基于鉴别委托的筛选器和在DeviceSpecific/Choice构造中使用一个基于比较的筛选器没有什么太大的区别,下面是使用基于鉴别委托的筛选器的代码片断:
  
  <mobile:Form id="Form1" runat="server">
  <mobile:Label id="Label1" runat="server" Text="Client is NOT MME on Sony">
  <DeviceSpecific>
  <Choice Text="Client is MME on Sony" Filter="isMMEonSony">
  </Choice>
  </DeviceSpecific>
  </mobile:Label>
  </mobile:Form>
  
     除了上面的方法外,你还可以在代码中使用MobileCapabilities.HasCapability方法来查看移动设备是否具备 isMMEonSony基于鉴别委托的筛选器的功能,如果设备具有指定的功能,则返回值为true,否则为false。在基于鉴别委托的筛选器这种情形 下,HasCapability方法的第二个参数是可选的,你可以为该参数设置一个有意义的String值。
  
    使用第二个参数的好处就 是你可以传递一些MobileCapabilities对象无法获取的移动设备信息到HasCapability方法中,例如我们知道HTTP文件头会传 送一些和移动设备相关的信息,我们可以使用System.Web.HttpRequest对象的属性获取移动设备的一些由 MobileCapabilities对象无法获取的其它信息。下面是具体的实现代码:
  
  if (((MobileCapabilities)Request.Browser).HasCapability(
  "isMMEonSony",
  Request.UserLanguages[0]))
  {
  // Do something.
  }
posted @ 2008-01-19 15:43 小罗 阅读(103) | 评论 (0)编辑
win2003 server下的IIS6默认设置下对每个运行在默认应用池中的工作者进程都会经过20多个小时后自动回收该进程,造成保存在该进程中的session丢失。


因为Session,Application等数据默认保存在运行该Web应用程序的工作者进程中,如果回收工作者进程,则会造成丢失。


解决办法:

修改配置,设置为不定时自动回收该工作者进程,比如设置为当超出占用现有物理内存60%后自动回收

该进程。通过使用默认应用程序池,可以确保多个应用程序间互相隔离,保证由于一个应用程序的崩溃不会影响另外的Web应用程序。还可以使一个独立的应用程序运行在一个指定的用户帐号特权之下。

如果使用StateServer方式或者Sql Server数据库方式来保存Session,则不受该设置的影响。


可能的原因2:

系统要运行在负载平衡的 Web 场环境中,而系统配置文件web.config中的Session状态却设置为InProc(即在本地存储会话状态),导至在用户访问量大时,Session常经超时的情况。引起这个现象的原因主要是因为用户通过负载平衡IP来访问WEB应用系统,某段时候在某台服务器保存了Session的会话状态,但在其它的WEB前端服务器中却没有保存Session的会话状态,而随着并发量的增大,负载平衡会当作路由随时访问空闲的服务器,结果空闲的服务器并没有之前保存的Session会话状态。


解决办法:
1.当您在负载平衡的 Web 场环境中运行 ASP.NET Web 应用程序时,一定要使用 SqlServer 或 StateServer 会话状态模式,在项目中我们基于性能考虑并没有选择SqlServer模式来存储Session状态,而是选择一台SessionStateServer 服务器来用户的Session会话状态。我们要在系统配置文件web.config中设置如下:
<sessionState mode="StateServer" cookieless="false" timeout="240" stateConnectionString="tcpip=192.168.0.1:42424" stateNetworkTimeout="14400" />

还要添加一项
<machineKey validationKey="78AE3850338BFADCE59D8DDF58C9E4518E7510149C46142D7AAD7F1AD49D95D4" decryptionKey="5FC88DFC24EA123C" validation="SHA1"/> 

2. 我们同时还要在SessionStateServer 服务器中启动ASP.NET State Service服务,具体设置:控制面板>>管理工具>>服务>>ASP.NET State Service,把它设为自动启动即可。 

3. 每台前端WEB服务的Microsoft“Internet 信息服务”(IIS)设置
             要在 Web 场中的不同 Web 服务器间维护会话状态,Microsoft“Internet 信息服务”(IIS) 配置数据库中 Web 站点的应用程序路径(例如,\LM\W3SVC\2)与 Web 场中所有 Web 服务器必须相同。大小写也必须相同,因为应用程序路径是区分大小写的。在一台 Web 服务器上,承载 ASP.NET 应用程序的 Web 站点的实例 ID 可能是 2(其中应用程序路径是 \LM\W3SVC\2)。在另一台 Web 服务器上,Web 站点的实例 ID 可能是 3(其中应用程序路径是 \LM\W3SVC\3)。因此,Web 场中的 Web 服务器之间的应用程序路径是不同的。我们必须使Web 场Web 站点的实例 ID 相同即可。你可以在IIS中把某一个WEB配置信息保存为一个文件,其他Web 服务器的IIS配置可以来自这一个文件。您如果想知道具体的设置请访问Microsoft Support网站:

posted @ 2008-01-19 15:41 小罗 阅读(126) | 评论 (0)编辑
<2009年1月>
28293031123
45678910
11121314151617
18192021222324
25262728293031
1234567

与我联系

搜索

 

常用链接

留言簿(5)

我的标签

随笔分类

随笔档案

文章分类

黎波 Mobile Business Solution - 博客园

最新评论

阅读排行榜

评论排行榜