趁上周周末空闲的时候,参考Subsonic的一些代码并模仿它的语法写了一个动态生成SQL语句的组件,主要是为了能提高一下开发效率。

实现原理这里就不细说了,有兴趣的朋友可以看一下源码,应该不难明白。

这里主要简单介绍以下个这个组件的用法:

1.  首先从最简单的开始,从一个表中获取其中几个列的数据

Code


以上的代码将会动态生成以下的SQL语句:"SELECT ProductID, ProductName FROM Products"
其中CreateProduct是个委托,方法签名是接收一个IDataReader的参数,返回值是一个实体类,这里的返回值就是Product这个实体类

2. 获取分页数据:

Code


以上代码将会产生以下的SQL语句:

WITH t AS (SELECT ROW_NUMBER() OVER(ORDER BY ProductID DESC) as row_number,*  FROM Products) Select * from t where row_number BETWEEN 1 and 20;Select count(0)  FROM Products;
 
这个SQL语句需要SQL 2005以上的数据才支持,还有使用分页必须加入排序,否则会报错。
PagerList这个类会有一个名叫TotalRecords的属性,也就是该次分页查询的总记录数。
 
3. 支持带()的表达式,以下的代码是一个NUit单元测试的代码:
Code
 
简单说明以下如果要使用带括号的表达式,必须使用AndExpression或者OrExpression。
使用AndExpression之后,其实就是在And之后先加入一个(,然后直到CloseExpression方法出现后才会加上)。
 
这个组件还支持In、Between、IsNull等一些操作,还有ToDataSet,First等一些获取数据的方法。
有兴趣的朋友可以下源码来看看,代码很简单的。
 
以下是下载地址:
 
posted @ 2009-03-31 00:42 小No 阅读(1492) | 评论 (9)编辑
     摘要: 前些时间看了玉开兄的“如此高效通用的分页存储过程是带有sql注入漏洞的”这篇文章,才突然想起某个项目也是使用了累似的通用分页存储过程。使用这种通用的存储过程进行分页查询,想要防SQL注入,只能对输入的参数进行过滤,例如将一个单引号“'”转换成两个单引号“''”,但这种做法是不安全的,厉害的黑客可以通过编码的方式绕过单引号的过滤... 阅读全文
posted @ 2008-11-28 16:05 小No 阅读(2419) | 评论 (29)编辑

趁上周周末空闲的时候,参考Subsonic的一些代码并模仿它的语法写了一个动态生成SQL语句的组件,主要是为了能提高一下开发效率。

实现原理这里就不细说了,有兴趣的朋友可以看一下源码,应该不难明白。

这里主要简单介绍以下个这个组件的用法:

1.  首先从最简单的开始,从一个表中获取其中几个列的数据

Code


以上的代码将会动态生成以下的SQL语句:"SELECT ProductID, ProductName FROM Products"
其中CreateProduct是个委托,方法签名是接收一个IDataReader的参数,返回值是一个实体类,这里的返回值就是Product这个实体类

2. 获取分页数据:

Code


以上代码将会产生以下的SQL语句:

WITH t AS (SELECT ROW_NUMBER() OVER(ORDER BY ProductID DESC) as row_number,*  FROM Products) Select * from t where row_number BETWEEN 1 and 20;Select count(0)  FROM Products;
 
这个SQL语句需要SQL 2005以上的数据才支持,还有使用分页必须加入排序,否则会报错。
PagerList这个类会有一个名叫TotalRecords的属性,也就是该次分页查询的总记录数。
 
3. 支持带()的表达式,以下的代码是一个NUit单元测试的代码:
Code
 
简单说明以下如果要使用带括号的表达式,必须使用AndExpression或者OrExpression。
使用AndExpression之后,其实就是在And之后先加入一个(,然后直到CloseExpression方法出现后才会加上)。
 
这个组件还支持In、Between、IsNull等一些操作,还有ToDataSet,First等一些获取数据的方法。
有兴趣的朋友可以下源码来看看,代码很简单的。
 
以下是下载地址:
 
posted @ 2009-03-31 00:42 小No 阅读(1492) | 评论 (9)编辑

上个礼拜,我的Azure邀请码终于到了,小兴奋了一把,于是马上去注册账号,并成功部署了一个网站到Azure上。

由于最近在学习Asp.Net Mvc框架,于是就想部署一个Mvc应用到Azure上,本来理所当然的认为Azure会支持Mvc,结果实际部署之后发现并不支持。

后来经过几次都不成功之后,有点想放弃了,不过幸好后来看到了以下这篇文章:

http://blogs.msdn.com/jnak/archive/2008/11/10/asp-net-mvc-on-windows-azure-with-providers.aspx

阅读了这篇文章,发现其实部署一个Mvc应用到Azure其实很简单,我按照里面所说的步骤很快就成功部署了一个应用。

这是我已经成功部署到Azure上的网站,大家可以先看看效果: http://np.cloudapp.net/ 

为了方便大家阅读,我在这里就简单的翻译一下,总结起来可以有以下几点:

1.  新建一个空的Cloud Service,例如叫:MVCCloudService。

        image 

2. 添加一个Asp.Net Mvc Application,例如叫MVCWebRole。

        image 

3. 卸载刚刚建的MVCWebRole项目。

        image 

4. 右键编辑MVCWebRole项目文件。

        image 

5. 把<RoleType>Web</RoleType>加到项目文件的第一个<PropertyGroup>中,并保存。就像以下那样:

<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup> 
     . . . 
    <RoleType>Web</RoleType>
<PropertyGroup>

6. 重新加载MVCWebRole项目。

       image 

7. 右键点击MVCCloudService项目的Roles节点,选择 Add -> Web Role Project in solution

    image    

    选择MVCWebRole 项目

    image 

8. 最后一步,也是很关键的一部。
    由于Azure上面没有安装ASP.NET MVC RC2,所以你必须把System.Web.Abstractions,System.Web.Mvc,System.Web.Routing这三个dll打包到服务包里面,部署到Azure之后你的网站才能运行正常。

    打包方法很简单,就是把MVCWebRole项目引用的这3个dll的复制本地属性设置为true就可以了。

     image      

到这里一个能部署到Azure上正常运行的Asp.net Mvc 应用就已经基本完成了,最后发布的步骤这里就不再啰嗦了,不懂得发布的可以到园子搜索一下,有很多关于如何发布一个应用到Azure的文章。

个人推荐浏牛木马的Azure Services Platform Step by Step系列文章:

http://www.cnblogs.com/azure/tag/Azure/

 

最后为了方便大家测试,我把按照以上步骤做好的源码共享给大家。 

源代码: http://files.cnblogs.com/NickYao/MVCCloudService.rar 

最后再补充说明一下,在vs 2008中Azure cloud service 项目和Mvc项目在同一个解决方案的话,是会是vs 2008崩溃的,解决办法就是去下载一个补丁,补丁地址是:https://connect.microsoft.com/VisualStudio/Downloads/DownloadDetails.aspx?DownloadID=16827&wa=wsignin1.0 

不过这个补丁不能用于Windows 7,哎。。。我就是在用windows7,白老鼠真的是要承受很多的不便。。。

 

 

posted @ 2009-03-17 13:26 小No 阅读(1953) | 评论 (14)编辑
Myspace和Facebook都是很优秀的社交类网站,它们拥有的用户和fans之多,大家都很清楚。
Myspace是一个基于.NET平台的,而Facebook更多是基于LAMP的。
我们来看看MySpace配合.NET+Windows Server 2003+Sql Server 2000/2005+IIS怎么创造传奇的


文章正文如下:

在每个里程碑,站点负担都会超过底层系统部分组件的最大载荷,特别是数据库和存储系统。接着,功能出现问题,用户失声尖叫。最后,技术团队必须为此修订系统策略。
虽然自2005年早期,站点账户数超过7百万后,系统架构到目前为止保持了相对稳定,但MySpace仍然在为SQL Server支持的同时连接数等方面继续攻坚,Benedetto说,"我们已经尽可能把事情做到最好"。


里程碑一:50万账户

按Benedetto 的说法,MySpace最初的系统很小,只有两台Web服务器和一个数据库服务器。那时使用的是Dell双CPU、4G内存的系统。

单个数据库就意味着所有数据都存储在一个地方,再由两台Web服务器分担处理用户请求的工作量。但就像MySpace后来的几次底层系统修订时的情况一样,三服务器架构很快不堪重负。此后一个时期内,MySpace基本是通过添置更多Web服务器来对付用户暴增问题的。

但到在2004年早期,MySpace用户数增长到50万后,数据库服务器也已开始汗流浃背。

但和Web服务器不同,增加数据库可没那么简单。如果一个站点由多个数据库支持,设计者必须考虑的是,如何在保证数据一致性的前提下,让多个数据库分担压力。

在第二代架构中,MySpace运行在3个SQL Server数据库服务器上——一个为主,所有的新数据都向它提交,然后由它复制到其他两个;另两个全力向用户供给数据,用以在博客和个人资料栏显示。这种方式在一段时间内效果很好——只要增加数据库服务器,加大硬盘,就可以应对用户数和访问量的增加。

里程碑二:1-2百万账户

MySpace注册数到达1百万至2百万区间后,数据库服务器开始受制于I/O容量——即它们存取数据的速度。而当时才是2004年中,距离上次数据库系统调整不过数月。用户的提交请求被阻塞,就像千人乐迷要挤进只能容纳几百人的夜总会,站点开始遭遇"主要矛盾",Benedetto说,这意味着MySpace永远都会轻度落后于用户需求。

"有人花5分钟都无法完成留言,因此用户总是抱怨说网站已经完蛋了。"他补充道。

这一次的数据库架构按照垂直分割模式设计,不同的数据库服务于站点的不同功能,如登录、用户资料和博客。于是,站点的扩展性问题看似又可以告一段落了,可以歇一阵子。

垂直分割策略利于多个数据库分担访问压力,当用户要求增加新功能时,MySpace将投入新的数据库予以支持它。账户到达2百万后,MySpace还从存储设备与数据库服务器直接交互的方式切换到SAN(Storage Area Network,存储区域网络)——用高带宽、专门设计的网络将大量磁盘存储设备连接在一起,而数据库连接到SAN。这项措施极大提升了系统性能、正常运行时间和可靠性,Benedetto说。

里程碑三:3百万账户

当用户继续增加到3百万后,垂直分割策略也开始难以为继。尽管站点的各个应用被设计得高度独立,但有些信息必须共享。在这个架构里,每个数据库必须有各自的用户表副本——MySpace授权用户的电子花名册。这就意味着一个用户注册时,该条账户记录必须在9个不同数据库上分别创建。但在个别情况下,如果其中某台数据库服务器临时不可到达,对应事务就会失败,从而造成账户非完全创建,最终导致此用户的该项服务无效。

另外一个问题是,个别应用如博客增长太快,那么专门为它服务的数据库就有巨大压力。

2004年中,MySpace面临Web开发者称之为"向上扩展"对"向外扩展"(译者注:Scale Up和Scale Out,也称硬件扩展和软件扩展)的抉择——要么扩展到更大更强、也更昂贵的服务器上,要么部署大量相对便宜的服务器来分担数据库压力。一般来说,大型站点倾向于向外扩展,因为这将让它们得以保留通过增加服务器以提升系统能力的后路。

但成功地向外扩展架构必须解决复杂的分布式计算问题,大型站点如Google、Yahoo和Amazon.com,都必须自行研发大量相关技术。以Google为例,它构建了自己的分布式文件系统。

另外,向外扩展策略还需要大量重写原来软件,以保证系统能在分布式服务器上运行。"搞不好,开发人员的所有工作都将白费",Benedetto说。

因此,MySpace首先将重点放在了向上扩展上,花费了大约1个半月时间研究升级到32CPU服务器以管理更大数据库的问题。Benedetto说,"那时候,这个方案看似可能解决一切问题。"如稳定性,更棒的是对现有软件几乎没有改动要求。

糟糕的是,高端服务器极其昂贵,是购置同样处理能力和内存速度的多台服务器总和的很多倍。而且,站点架构师预测,从长期来看,即便是巨型数据库,最后也会不堪重负,Benedetto说,"换句话讲,只要增长趋势存在,我们最后无论如何都要走上向外扩展的道路。"

因此,MySpace最终将目光移到分布式计算架构——它在物理上分布的众多服务器,整体必须逻辑上等同于单台机器。拿数据库来说,就不能再像过去那样将应用拆分,再以不同数据库分别支持,而必须将整个站点看作一个应用。现在,数据库模型里只有一个用户表,支持博客、个人资料和其他核心功能的数据都存储在相同数据库。

既然所有的核心数据逻辑上都组织到一个数据库,那么MySpace必须找到新的办法以分担负荷——显然,运行在普通硬件上的单个数据库服务器是无能为力的。这次,不再按站点功能和应用分割数据库,MySpace开始将它的用户按每百万一组分割,然后将各组的全部数据分别存入独立的SQL Server实例。目前,MySpace的每台数据库服务器实际运行两个SQL Server实例,也就是说每台服务器服务大约2百万用户。Benedetto指出,以后还可以按照这种模式以更小粒度划分架构,从而优化负荷分担。

当然,还是有一个特殊数据库保存了所有账户的名称和密码。用户登录后,保存了他们其他数据的数据库再接管服务。特殊数据库的用户表虽然庞大,但它只负责用户登录,功能单一,所以负荷还是比较容易控制的。

里程碑四:9百万到1千7百万账户

2005年早期,账户达到9百万后,MySpace开始用Microsoft的C#编写ASP.NET程序。C#是C语言的最新派生语言,吸收了C++和Java的优点,依托于Microsoft .NET框架(Microsoft为软件组件化和分布式计算而设计的模型架构)。ASP.NET则由编写Web站点脚本的ASP技术演化而来,是Microsoft目前主推的Web站点编程环境。

可以说是立竿见影, MySpace马上就发现ASP.NET程序运行更有效率,与ColdFusion相比,完成同样任务需消耗的处理器能力更小。据技术总监Whitcomb说,新代码需要150台服务器完成的工作,如果用ColdFusion则需要246台。Benedetto还指出,性能上升的另一个原因可能是在变换软件平台,并用新语言重写代码的过程中,程序员复审并优化了一些功能流程。

最终,MySpace开始大规模迁移到ASP.NET。即便剩余的少部分ColdFusion代码,也从Cold-Fusion服务器搬到了ASP.NET,因为他们得到了BlueDragon.NET(乔治亚州阿尔法利塔New Atlanta Communications公司的产品,它能将ColdFusion代码自动重新编译到Microsoft平台)的帮助。

账户达到1千万时,MySpace再次遭遇存储瓶颈问题。SAN的引入解决了早期一些性能问题,但站点目前的要求已经开始周期性超越SAN的I/O容量——即它从磁盘存储系统读写数据的极限速度。

原因之一是每数据库1百万账户的分割策略,通常情况下的确可以将压力均分到各台服务器,但现实并非一成不变。比如第七台账户数据库上线后,仅仅7天就被塞满了,主要原因是佛罗里达一个乐队的歌迷疯狂注册。

某个数据库可能因为任何原因,在任何时候遭遇主要负荷,这时,SAN中绑定到该数据库的磁盘存储设备簇就可能过载。"SAN让磁盘I/O能力大幅提升了,但将它们绑定到特定数据库的做法是错误的。"Benedetto说。

最初,MySpace通过定期重新分配SAN中数据,以让其更为均衡的方法基本解决了这个问题,但这是一个人工过程,"大概需要两个人全职工作。"Benedetto说。

长期解决方案是迁移到虚拟存储体系上,这样,整个SAN被当作一个巨型存储池,不再要求每个磁盘为特定应用服务。MySpace目前采用了一种新型SAN设备——来自加利福尼亚州弗里蒙特的3PARdata。

在3PAR的系统里,仍能在逻辑上按容量划分数据存储,但它不再被绑定到特定磁盘或磁盘簇,而是散布于大量磁盘。这就使均分数据访问负荷成为可能。当数据库需要写入一组数据时,任何空闲磁盘都可以马上完成这项工作,而不再像以前那样阻塞在可能已经过载的磁盘阵列处。而且,因为多个磁盘都有数据副本,读取数据时,也不会使SAN的任何组件过载。

当2005年春天账户数达到1千7百万时,MySpace又启用了新的策略以减轻存储系统压力,即增加数据缓存层——位于Web服务器和数据库服务器之间,其唯一职能是在内存中建立被频繁请求数据对象的副本,如此一来,不访问数据库也可以向Web应用供给数据。换句话说,100个用户请求同一份资料,以前需要查询数据库100次,而现在只需1次,其余都可从缓存数据中获得。当然如果页面变化,缓存的数据必须从内存擦除,然后重新从数据库获取——但在此之前,数据库的压力已经大大减轻,整个站点的性能得到提升。

缓存区还为那些不需要记入数据库的数据提供了驿站,比如为跟踪用户会话而创建的临时文件——Benedetto坦言他需要在这方面补课,"我是数据库存储狂热分子,因此我总是想着将万事万物都存到数据库。"但将像会话跟踪这类的数据也存到数据库,站点将陷入泥沼。

增加缓存服务器是"一开始就应该做的事情,但我们成长太快,以致于没有时间坐下来好好研究这件事情。"Benedetto补充道。

里程碑五:2千6百万账户

2005年中期,服务账户数达到2千6百万时,MySpace切换到了还处于beta测试的SQL Server 2005。转换何太急?主流看法是2005版支持64位处理器。但Benedetto说,"这不是主要原因,尽管这也很重要;主要还是因为我们对内存的渴求。"支持64位的数据库可以管理更多内存。

更多内存就意味着更高的性能和更大的容量。原来运行32位版本的SQL Server服务器,能同时使用的内存最多只有4G。切换到64位,就好像加粗了输水管的直径。升级到SQL Server 2005和64位Windows Server 2003后,MySpace每台服务器配备了32G内存,后于2006年再次将配置标准提升到64G。

意外错误

如果没有对系统架构的历次修改与升级,MySpace根本不可能走到今天。但是,为什么系统还经常吃撑着了?很多用户抱怨的"意外错误"是怎么引起的呢?

原因之一是MySpace对Microsoft的Web技术的应用已经进入连Microsoft自己也才刚刚开始探索的领域。比如11月,超出SQL Server最大同时连接数,MySpace系统崩溃。Benedetto说,这类可能引发系统崩溃的情况大概三天才会出现一次,但仍然过于频繁了,以致惹人恼怒。一旦数据库罢工,"无论这种情况什么时候发生,未缓存的数据都不能从SQL Server获得,那么你就必然看到一个'意外错误'提示。"他解释说。

去年夏天,MySpace的Windows 2003多次自动停止服务。后来发现是操作系统一个内置功能惹的祸——预防分布式拒绝服务攻击(黑客使用很多客户机向服务器发起大量连接请求,以致服务器瘫痪)。MySpace和其他很多顶级大站点一样,肯定会经常遭受攻击,但它应该从网络级而不是依靠Windows本身的功能来解决问题——否则,大量MySpace合法用户连接时也会引起服务器反击。

"我们花了大约一个月时间寻找Windows 2003服务器自动停止的原因。"Benedetto说。最后,通过Microsoft的帮助,他们才知道该怎么通知服务器:"别开枪,是友军。"

紧接着是在去年7月某个周日晚上,MySpace总部所在地洛杉矶停电,造成整个系统停运12小时。大型Web站点通常要在地理上分布配置多个数据中心以预防单点故障。本来,MySpace还有其他两个数据中心以应对突发事件,但Web服务器都依赖于部署在洛杉矶的SAN。没有洛杉矶的SAN,Web服务器除了恳求你耐心等待,不能提供任何服务。

Benedetto说,主数据中心的可靠性通过下列措施保证:可接入两张不同电网,另有后备电源和一台储备有30天燃料的发电机。但在这次事故中,不仅两张电网失效,而且在切换到备份电源的过程中,操作员烧掉了主动力线路。

2007年中,MySpace在另两个后备站点上也建设了SAN。这对分担负荷大有帮助——正常情况下,每个SAN都能负担三分之一的数据访问量。而在紧急情况下,任何一个站点都可以独立支撑整个服务,Benedetto说。

MySpace仍然在为提高稳定性奋斗,虽然很多用户表示了足够信任且能原谅偶现的错误页面。

"作为开发人员,我憎恶Bug,它太气人了。"Dan Tanner这个31岁的德克萨斯软件工程师说,他通过MySpace重新联系到了高中和大学同学。"不过,MySpace对我们的用处很大,因此我们可以原谅偶发的故障和错误。" Tanner说,如果站点某天出现故障甚至崩溃,恢复以后他还是会继续使用。

这就是为什么Drew在论坛里咆哮时,大部分用户都告诉他应该保持平静,如果等几分钟,问题就会解决的原因。Drew无法平静,他写道,"我已经两次给MySpace发邮件,而它说一小时前还是正常的,现在出了点问题……完全是一堆废话。"另一个用户回复说,"毕竟它是免费的。"Benedetto坦承100%的可靠性不是他的目标。"它不是银行,而是一个免费的服务。"他说。

换句话说,MySpace的偶发故障可能造成某人最后更新的个人资料丢失,但并不意味着网站弄丢了用户的钱财。"关键是要认识到,与保证站点性能相比,丢失少许数据的故障是可接受的。"Benedetto说。所以,MySpace甘冒丢失2分钟到2小时内任意点数据的危险,在SQL Server配置里延长了"checkpoint"操作——它将待更新数据永久记录到磁盘——的间隔时间,因为这样做可以加快数据库的运行。

Benedetto说,同样,开发人员还经常在几个小时内就完成构思、编码、测试和发布全过程。这有引入Bug的风险,但这样做可以更快实现新功能。而且,因为进行大规模真实测试不具可行性,他们的测试通常是在仅以部分活跃用户为对象,且用户对软件新功能和改进不知就里的情况下进行的。因为事实上不可能做真实的加载测试,他们做的测试通常都是针对站点。

"我们犯过大量错误,"Benedetto说,"但到头来,我认为我们做对的还是比做错的多。"

MySpace Tech Roster
January 16, 2007
By David F. Carr
------------------------------------------------

个人的几个观点:
1,.NET平台很牛,很强大。
2,对于技术而言,局限性往往存在于程序员自身。
3,网站的分布式更多是为了提高性能,否则不要开始分布式。
4,网站的分布式更多体现在数据库方面,和目前.NET平台主流的分布式技术有点不同。
5,.NET平台企业级开发的分布式解决方案有很多,选择适合企业自身特点的才是最理想的。

posted @ 2009-03-13 16:13 小No 阅读(49) | 评论 (2)编辑

企业内部网站一般采用windwos身分验证机制。主要包括两部分
一、程序代码中读取当前windows用户帐号
二、IIS和ASP.NET的web.config设置


一、这段代码可以取出当前windows用户的帐号,

string strUser;
System.Security.Principal.WindowsIdentity objIden = System.Security.Principal.WindowsIdentity.GetCurrent();
strUser = objIden.Name;//Domain and alias

 

二、IIS本身可以设置目录的访问控制,ASP.NET的web.config中也可以设置访问控制。如果要达到特定的身份认证目的,需要合理设置,设置不当会造成很多问题。
通常的设置:IIS 采用windwos集成身份验证,web.config中添加<identity impersonate="true"/>。

1 IIS的虚目录的身份设置:
匿名用户:任何用户访问此网站都不需要登录。
Windows集成身份验证:客户端访问此网站,需要提交自己的身份。如果客户端是XP,提交的身份就是当前运行IE的用户帐号,如果客户端是windows 2003,IE会跳出登录窗体让你登录。

2 ASP.NET身份验证,
在web.config文件中,可以通过设置<identity impersonate="true"/>,打开身份模拟。
默认情况下,是没有身份模拟的,此时,如果用程序读取当前的windows用户,取得的是运行当前进程的windows账号。
如果网站运行在Windows XP上,读出的当前用户是ASPNET,如果网站运行在Windows2003上,当前用户是网站对应应用程序池的运行账号,一般是network service。
设置了<identity impersonate="true"/>后,如果用程序读取当前的windows用户,取得的是客户端访问网站所使用的windows账号。

下面的列表,列出了IIS,web.config设置对当前的windows用户的影响

表一:网站运行在Windows XP上

 

IIS设置 anonymouse access anonymouse access integrated windows authentication integrated windows authentication
web.config设置 此处无论<authentication mode="XXXXX"/>结果都一样 <identity impersonate="true"/> 此处无论<authentication mode="XXXXX"/>结果都一样 <identity impersonate="true"/>
取得current user的名字 ASPNET IUSR_CVIS-TEST1 ASPNET v-ricyan(login)
备注 XP,Windows2003都不需要登录 XP,Windows2003都不需要登录,此时取得的IUSR_CVIS-TEST1是anonymouse默认运行的账户 XP客户端不需要登录,windows2003客户端需要登录 XP客户端不需要登录,windows2003客户端需要登录

 表二:网站运行在Windows2003

IIS设置 anonymouse access anonymouse access integrated windows authentication integrated windows authentication
web.config设置 此处无论<authentication mode="XXXXX"/>结果都一样 <identity impersonate="true"/> 此处无论<authentication mode="XXXXX"/>结果都一样 <identity impersonate="true"/>
取得current user的名字 SYSTEM IUSR_CVIS-TEST1 SYSTEM v-ricyan(login)
备注 XP,Windows2003都不需要登录。这时取得的用户是application pool运行账户,我把运行账户设置为本地系统用户了 XP,Windows2003都不需要登录,此时取得的IUSR_CVIS-TEST1是anonymouse默认运行的账户 XP,Windows2003都不需要登录。这时取得的用户是application pool运行账户,我把运行账户设置为本地系统用户了 XP客户端不需要登录,windows2003客户端需要登录
posted @ 2009-03-12 10:20 小No 阅读(144) | 评论 (0)编辑

概述

Win+Up

最大化
Win+Down 还原 / 最小化
Win+Left 通过AeroSnap靠左显示
Win+Right 通过AeroSnap靠右显示
Win+Shift+Left 跳转左边的显示器
Win+Shift+Right 跳转右边的显示器
Win+Home 最小化 / 还原所有其他窗口
Win+T 选中任务栏首个项目
再次按下则会在任务栏上循环切换
Win+Shift+T 则是后退
Win+Space 使用Aero Peek显示桌面
Win+G 呼出桌面小工具
Win+P 外界显示器(扩展桌面等)
Win+X 移动中心
Win+#
(# = 数字键)

运行任务栏上第N个程序

比如: Win+1 使用第一个程序, Win+2 使用第二个...

Win + +
Win + -
(plus or minus key)
放大/缩小

资源管理器

Alt+P 显示/隐藏 预览面板

任务栏

Shift + 左键单击某程序图标 运行
中键单击某程序图标 运行
Ctrl + Shift + 左键单击某程序图标 以管理员身份运行
Shift + 右键击某程序图标 显示窗口菜单(还原 / 最小化/ 移动 / 等)
Note: 通常可以右键窗口的任务栏预览呼出此菜单
Shift + 右击某程序图标(分组显示窗口模式下) 呼出还原所有窗口 / 最小化所有窗口 / 关闭所有窗口等菜单
Ctrl + 左键单击某程序图标(分组显示窗口模式下) 在窗口或标签中循环切换

 

posted @ 2009-01-19 10:12 小No 阅读(52) | 评论 (0)编辑
     摘要: 前些时间看了玉开兄的“如此高效通用的分页存储过程是带有sql注入漏洞的”这篇文章,才突然想起某个项目也是使用了累似的通用分页存储过程。使用这种通用的存储过程进行分页查询,想要防SQL注入,只能对输入的参数进行过滤,例如将一个单引号“'”转换成两个单引号“''”,但这种做法是不安全的,厉害的黑客可以通过编码的方式绕过单引号的过滤... 阅读全文
posted @ 2008-11-28 16:05 小No 阅读(2419) | 评论 (29)编辑

原文地址:http://www.cnblogs.com/yizhu2000/archive/2007/12/04/982142.html

本人作为一位web工程师,着眼最多之处莫过于 性能与架构,本次幸得参与sd2.0大会,得以与同行广泛交流,于此二方面,有些心得,不敢独享,与众博友分享,本文是这次参会与众同撩交流的心得,有兴趣者可以查看视频

架构设计的几个心得:


一,不要过设计:never over design

这是一个常常被提及的话题,但是只要想想你的架构里有多少功能是根本没有用到,或者最后废弃的,就能明白其重要性了,初涉架构设计,往往倾向于设计大而化一的架构,希望设计出具有无比扩展性,能适应一切需求的增加架构,web开发领域是个非常动态的过程,我们很难预测下个星期的变化,而又需要对变化做出最快最有效的响应。。

ebay的工程师说过,他们的架构设计从来都不能满足系统的增长,所以他们的系统永远都在推翻重做。请注意,不是ebay架构师的能力有问题,他们设计的架构总是建立旧版本的瓶颈上,希望通过新的架构带来突破,然而新架构带来的突破总是在很短的时间内就被新增需求淹没,于是他们不得不又使用新的架构
web开发,是个非常敏捷的过程,变化随时都在产生,用户需求千变万化,许多方面偶然性非常高,较之软件开发,希望用一个架构规划以后的所有设计,是不现实的

二,web架构生命周期:web architecture‘s life cycle


既然要杜绝过设计,又要保证一定的前瞻性,那么怎么才能找到其中的平衡呢?希望下面的web架构生命周期能够帮到你

architecture_life_cycle

所设计的架构需要在1-10倍的增长下,通过简单的增加硬件容量就能够胜任,而在5-10倍的增长期间,请着手下一个版本的架构设计,使之能承受下一个10倍间的增长

google之所以能够称霸,不完全是因为搜索技术和排序技术有多先进,其实包括baidu和yahoo,所使用的技术现在也已经大同小异,然而,google能在一个月内通过增加上万台服务器来达到足够系统容量的能力确是很难被复制的


三,缓存:Cache


空间换取时间,缓存永远计算机设计的重中之重,从cpu到io,到处都可以看到缓存的身影,web架构设计重,缓存设计必不可少,关于怎样设计合理的缓存,jbosscache的创始人,淘宝的创始人是这样说的:其实设计web缓存和企业级缓存是非常不同的,企业级缓存偏重于逻辑,而web缓存,简单快速为好。。

缓存带来的问题是什么?是程序的复杂度上升,因为数据散布在多个进程,所以同步就是一个麻烦的问题,加上集群,复杂度会进一步提高,在实际运用中,采用怎样的同步策略常常需要和业务绑定

老钱为搜狐设计的帖子设计了链表缓存,这样既可以满足灵活插入的需要,又能够快速阅读,而其他一些大型社区也经常采用类此的结构来优化帖子列表,memcache也是一个常常用到的工具

钱宏武谈架构设计视频 http://211.100.26.82/CSDN_Live/140/qhw.flv

Cache的常用的策略是:让数据在内存中,而不是在比较耗时的磁盘上。从这个角度讲,mysql提供的heap引擎(存储方式)也是一个值得思考的方法,这种存储方法可以把数据存储在内存中,并且保留sql强大的查询能力,是不是一举两得呢?

我们这里只说到了读缓存,其实还有一种写缓存,在以内容为主的社区里比较少用到,因为这样的社区最主要需要解决的问题是读问题,但是在处理能力低于请求能力时,或者单个希望请求先被缓存形成块,然后批量处理时,写缓存就出现了,在交互性很强的社区设计里我们很容易找到这样的缓存

四,核心模块一定要自己开发:DIY your core module


这点我们是深有体会,钱宏武和云风也都有谈到,我们经常倾向于使用一些开源模块,如果不涉及核心模块,确实是可以的,如果涉及,那么就要小心了,因为当访问量达到一定的程度,这些模块往往都有这样那样的问题,当然我们可以把问题归结为对开源的模块不熟悉,但是不管怎样,核心出现问题的时候,不能完全掌握其代码是非常可怕的


五,合理选择数据存储方式:reasonable data storage


我们一定要使用数据库吗,不一定,雷鸣告诉我们搜索不一定需要数据库,云风告诉我们,游戏不一定需要数据库,那么什么时候我们才需要数据库呢,为什么不干脆用文件来代替他呢?
首先我们需要先承认,数据库也是对文件进行操作。我们需要数据库,主要是使用下面这几个功能,一个是数据存储,一个是数据检索,在关系数据库中,我们其实非常在乎数据库的复杂搜索的能力,看看一个统计用的tsql就知道了(不用仔细读,扫一眼就可以了)

select   c.Class_name,d.Class_name_2,a.Creativity_Title,b.User_name,(select   count(Id)   from   review   where   Reviewid=a.Id)   as   countNum   from   Creativity   as   a,User_info   as   b,class   as   c,class2   as   d   where   a.user_id=b.id   and   a.Creativity_Class=c.Id   and   a.Creativity_Class_2=d.Id
select   a.Id,max(c.Class_name),(max(d.Class_name_2),max(a.Creativity_Title),max(b.User_name),count(e.Id)   as   countNum   from   Creativity   as   a,User_info   as   b,class   as   c,class2   as   d,review   as   e   where   a.user_id=b.id   and   a.Creativity_Class=c.Id   and   a.Creativity_Class_2=d.Id   and   a.Id=e.Reviewid   group   by   a.Id ..............................................

我们可以看出需要数据库关联,排序的能力,这个能力在某些情况下非常重要,但是如果你的网站的常规操作,全是这样复杂的逻辑,那效率一定是非常低的,所以我们常常在数据库里加入许多冗余字段,来减小简单查询时关联等操作带来的压力,我们看看下面这张图,可以看到数据库的设计重心,和网站(指内容型社区)需要面对的问题实际是有一些偏差的

database

同样其他一些软件产品也遇到同样的问题所以具我了解,有许多特殊的运用都有自己设计的特殊数据存储结构与方法,比如有的大型服务程序采取树形数据存储结构,lucene使用文件来存储索引和文件

从另外一个角度上看,使用数据库,意味着数据和表现是完全分离的(这当然是经典的设计思路),也就是说当需要展示数据时,不得不需要一个转换的过程,也可以说是绑定的过程,当网站具备一定规模的时候,数据库往往成为效率的瓶颈,所以许多网站也采用直接书写静态文件的方法来避免读取操作时的绑定

这并不是说我们从今天起就可以把我们亲爱的数据库打入冷宫,而是我们在设计数据的持久化时,需要根据实际情况来选择存储方式,而数据库不过是其中一个选项


六,搞清楚谁是最重要的人:who's the most important guy


在用例需求分析的时候常常讲到涉众,就是和你的设计息息相关的人,在web中我们一定以为最重要的涉众莫过于用户了。,在一个传统的互动社区开发中,最重要的东西是内容,用户产生内容,所以用户就是上帝,至于内容挑选工具,不就是给坐我后面三排的妹妹们用的吗?凑或行了,实在有问题我就在数据里手动帮你加得了。。这大概是眼下许多小型甚至中型网站技术人员的普遍想法。钱宏武在他的讲座里谈到了这个问题:实际上网站每天产生的内容非常的多,普通人是不可能看完的,而编辑负责把精华的内容推荐到首页上,所以很多用户读到的内容其实都依赖于编辑的推荐,所以设计让编辑工作方便的工具也是非常重要,有时甚至是最重要的。


七,不要执着于文档:don't be crazy about document


web开发的文档重要吗?什么文档最重要?我的看法是web开发中交流>文档,

现在大的软件公司比较流行的做法是:
注重产品设计文档,在这种方法里,产品文档非常详尽,并且没有歧义,开发人员基于设计文档开发,测试人员基于设计文档制定测试方案,任何新人都可以通过阅读产品设计文档来了解项目的概况

而web项目从概念到实现的时间是非常短的,而且越短越好,并且由于变化迅速,要想写出完整的产品和需求文档是几乎不可能的,大多数情况是等你写出完备的文档,项目早就是另外一个样子,但是没有文档的问题是,如果团队发生变化,添加新成员怎样才能了解软件的结构和概念呢,一种是每个人都了解软件的整个结构,除非你的团队整体消失,否则任何一个人都能够担当培养新人的责任,这种face2face交流比文档有效率很多。

于是就有了前office开发者,现任yahoo中国某产品开发负责人的刘振飞所感觉到的落差,他说,我们的项目是吵出来的,我听完会心一笑


八,团队:team


不要专家团队,而要外科手术式的团队,你的团队里一定要有清道夫,需要有弓箭手,让他们和项目一起成长,才是项目负责人的最大成就

 

总结:

0)架构是一种权衡

architecture

1)web开发的特点是是:没有太复杂的技术难点,一切在于迅速的把握需求,其实这正式敏捷开发的要旨所在,一切都可以非常快速的建立,非常快速的重构,我们的开发工具,底层库和框架,包括搜索引擎和web文档提供的帮助,都提我们供给了敏捷的能力。

2)此外,相应的,最有效率的交流方式必须留给web开发,那就是face2face(面对面),不要太担心你的设计不能被完备的文档所保留下来,他们会以交流,代码和小卡片的方式保存下来

3)人的因素会更加重要,无论是对用户的需求,还是开发人员的素质。

 

另:有关web效率,有著名的14条规则,由yahoo性能效率小组所总结,并广为流传。业已出现相关插件(YSlow),针对具体网页按彼规则评分,这次该小组负责人Tenni Theurer也受邀来到此次大会,我把Tenni小姐(之前真的没有想到她是个女孩,并且如此年轻)和她的团队的14 rules列在下面

  • Make Fewer HTTP Requests
  • Use a Content Delivery Network
  • Add an Expires Header
  • Gzip Components
  • Put CSS at the Top
  • Move Scripts to the Bottom
  • Avoid CSS Expressions
  • Make JavaScript and CSS External
  • Reduce DNS Lookups
  • Minify JavaScript
  • Avoid Redirects
  • Remove Duplicate Scripts
  • Configure ETags
  • Make Ajax Cacheable

     

    通过安装firebugYSlow这两个firefox插件(请注意要先安装firebug再安装yslow,下载后拖动到firefox里即可)我们可以看到你的网页根据下面的规则的评分,这是我在博客园博客首页的评分截图,上面D表示总分,下面是单项评分,A最好F最差,不知道还有没有G :)

    YSlow

     

    相关连接

    yahoo性能团队:http://developer.yahoo.com/performance/

     

  • posted @ 2008-09-22 10:59 小No 阅读(57) | 评论 (0)编辑

    转发这篇文章主要是原作者BLOG的主题的字体太小,看得不太舒服~~

     

    对于一个真正的企业级的应用来说,Caching肯定是一个不得不考虑的因素,合理、有效地利用Caching对于 增强应用的Performance(减少对基于Persistent storage的IO操作)、Scalability(将数据进行缓存,减轻了对Database等资源的压力)和Availability(将数据进行 缓存,可以应对一定时间内的网络问题、Web Service不可访问问题、Database的崩溃问题等等)。Enterprise Library的Caching Application Block为我们提供了一个易用的、可扩展的实现Caching的框架。借助于Caching Application Block,Administrator和Developer很容易实现基于Caching的管理和编程。由于Caching的本质在于将相对稳定的数据 常驻内存,以避免对Persistent storage的IO操作的IO操作,所以有两个棘手的问题:Load Balance问题;Persistent storage和内存中数据同步的问题。本篇文章提供了一个解决方案通过SqlDependency实现SQL Server中的数据和Cache同步的问题。

    一、Cache Item的过期策略

    在 默认的情况下,通过CAB(以下对Caching Application Block的简称,注意不是Composite UI Application Block )的CacheManager加入的cache item是永不过期的;但是CacheManager允许你在添加cache item的时候通过一个ICacheItemExpiration对象应用不同的过期策略。CAB定了一个以下一些class实现了 ICacheItemExpiration,以提供不同的过期方式:

    • AbsoluteTime:为cache item设置一个cache item的绝对过期时间。
    • ExtendedFormatTime:通过一个表达式实现这样的过期策略:每分钟过期(*****:5个*分别代表minute、hour、date、month、year);每个小时的第5分钟过期(5****);每个月的2号零点零分过期(0 0 2 * *)。
    • FileDependency:将cache item和一个file进行绑定,通过检测file的最后更新时间确定file自cache item被添加以来是否进行过更新。如果file已经更新则cache item过期。
    • NeverExpired:永不过期。
    • SlidingTime:一个滑动的时间,cache item的每次获取都将生命周期延长到设定的时间端,当cache item最后一次获取的时间算起,超出设定的时间,则cache item过期。

    对 于过期的cache item,会及时地被清理。所以要实现我们开篇提出的要求:实现Sql Server中的数据和Cache中的数据实现同步,我们可以通过创建基于Sql Server数据变化的cache item的过期策略。换句话说,和FileDependency,当Persistent storage(Database)的数据变化本检测到之后,对于得cache自动过期。但是,对于文件的修改和删除,我们和容易通过文件的最后更新日期 或者是否存在来确定。对于Database中Table数据的变化的探测就不是那么简单了。不过SQL Server提供了一个SqlDependency的组建帮助我们很容易地实现了这样的功能。

    二、创建基于SqlDependency的ICacheItemExpiration

    SqlDependency 是建立在SQL Server 2005的Service Broker之上。SqlDependency向SQL Server订阅一个Query Notification。当SQL Server检测到基于该Query的数据发生变化,向SqlDependency发送一个Notification,并触发SqlDependency 的Changed事件,我们就可以通过改事件判断对应的cache item是否应该过期。

    我们现在就来创建这样的一个ICacheItemExpiration。我们先看看ICacheItemExpiration的的定义:

    public interface ICacheItemExpiration
    {
        // Methods
        bool HasExpired();
        void Initialize(CacheItem owningCacheItem);
        void Notify();
    }

    而 判断过期的依据就是根据HasExpired方法,我们自定义的CacheItemExpiration就是实现了该方法,根据 SqlDependency判断cache item是否过期。下面是SqlDependencyExpiration的定义(注:SqlDependencyExpiration的实现通过 Enterprise Library DAAB实现DA操作):

    namespace Artech.SqlDependencyCaching
    {
        public class SqlDependencyExpiration : ICacheItemExpiration
        {
            private static readonly CommandType DefaultComamndType = CommandType.StoredProcedure;

            public event EventHandler Expired;

            public bool HasChanged
            { get; set; }

            public string ConnectionName
            { get; set; }

            public SqlDependencyExpiration(string commandText, IDictionary<string, object> parameters) :
                this(commandText, DefaultComamndType, string.Empty, parameters)
            { }

            public SqlDependencyExpiration(string commandText, string connectionStringName, IDictionary<string, object> parameters) :
                this(commandText, DefaultComamndType, connectionStringName, parameters)
            { }

            public SqlDependencyExpiration(string commandText, CommandType commandType, IDictionary<string, object> parameters) :
                this(commandText, commandType, string.Empty, parameters)
            { }

            public SqlDependencyExpiration(string commandText, CommandType commandType, string connectionStringName, IDictionary<string, object> parameters)
            {
                if (string.IsNullOrEmpty(connectionStringName))
                {
                    this.ConnectionName = DatabaseSettings.GetDatabaseSettings(ConfigurationSourceFactory.Create()).DefaultDatabase;
                }
                else
                {
                    this.ConnectionName = connectionStringName;
                }

                SqlDependency.Start(ConfigurationManager.ConnectionStrings[this.ConnectionName].ConnectionString);
                using (SqlConnection sqlConnection = DatabaseFactory.CreateDatabase(this.ConnectionName).CreateConnection() as SqlConnection)
                {
                    SqlCommand command = new SqlCommand(commandText, sqlConnection);
                    command.CommandType = commandType;
                    if (parameters != null)
                    {
                        this.AddParameters(command, parameters);
                    }
                 SqlDependency dependency = new SqlDependency(command);
                    dependency.OnChange += delegate
                    {
                        this.HasChanged = true;
                        if (this.Expired != null)
                        {
                            this.Expired(this, new EventArgs());
                        }
                    };
                    if (sqlConnection.State != ConnectionState.Open)
                    {
                        sqlConnection.Open();
                    }
                    command.ExecuteNonQuery();
                }
            }

            private void AddParameters(SqlCommand command, IDictionary<string, object> parameters)
            {
                command.Parameters.Clear();
                foreach (var parameter in parameters)
                {
                    string parameterName = parameter.Key;
                    if (!parameter.Key.StartsWith("@"))
                    {
                        parameterName = "@" + parameterName;
                    }

                    command.Parameters.Add(new SqlParameter(parameterName, parameter.Value));
                }
            }

            #region ICacheItemExpiration Members

            public bool HasExpired()
            {
                bool indicator = this.HasChanged;
                this.HasChanged = false;
                return indicator;
            }

            public void Initialize(CacheItem owningCacheItem)
            {         }

            public void Notify()
            {         }

            #endregion
        }
    }

    我们来简单分析一下实现过程,先看看Property定义:

    private static readonly CommandType DefaultComamndType = CommandType.StoredProcedure;

    public event EventHandler Expired;

    public bool HasChanged
    { get; set; }

    public string ConnectionName
    { get; set; }

    通 过DefaultComamndType 定义了默认的CommandType,在这了我默认使用Stored Procedure;Expired event将在cache item过期时触发;HasChanged代表Database的数据是否被更新,将作为cache过期的依据;ConnectionName代表的是 Connection string的名称。

    为了使用上的方便,我定义了4个重载的构造函 数,最后的实现定义在public SqlDependencyExpiration(string commandText, CommandType commandType, string connectionStringName, IDictionary<string, object> parameters)。parameters代表commandText的参数列表,key为参数名称,value为参数的值。首先获得真正的 connection string name(如果参数connectionStringName为空,就使用DAAB默认的connection string)

    if (string.IsNullOrEmpty(connectionStringName))
    {
         this.ConnectionName = DatabaseSettings.GetDatabaseSettings(ConfigurationSourceFactory.Create()).DefaultDatabase;
    }
    else
    {
         this.ConnectionName = connectionStringName;
    }

    然 后通过调用SqlDependency.Start()方法,并传入connection string作为参数。该方法将创建一个Listener用于监听connection string代表的database instance发送过来的query notifucation。

    SqlDependency.Start(ConfigurationManager.ConnectionStrings[this.ConnectionName].ConnectionString);

    然 后创建SqlConnection,并根据CommandText和CommandType参数创建SqlCommand对象,并将参数加入到 command的参数列表中。最后将这个SqlCommand对象作为参数创建SqlDependency 对象,并注册该对象的OnChange 事件(对HasChanged 赋值;并触发Expired事件)。这样当我们执行该Cmmand之后,当基于commandtext的select sql语句获取的数据在database中发生变化(添加、更新和删除),SqlDependency 的OnChange 将会触发

    SqlDependency dependency = new SqlDependency(command);
    dependency.OnChange += delegate
    {
          this.HasChanged = true;
           if (this.Expired != null)
           {
                  this.Expired(this, new EventArgs());

           }
            
    };
    这样在HasExpired方法中,就可以根据HasChanged 属性判断cache item是否应该过期了。

    public bool HasExpired()
    {
         bool indicator = this.HasChanged;
         this.HasChanged = false;
         return indicator;
    }

    三、如何应用SqlDependencyExpiration

    我 们现在创建一个简单的Windows Application来模拟使用我们创建的SqlDependencyExpiration。我们模拟一个简单的场景:假设我们有一个功能需要向系统所 有的user发送通知,而且不同的user,通知是不一样的,由于通知的更新的频率不是很高,我们需要讲某个User的通知进行缓存。

    这是我们的表结构:Messages

    image

    我们通过下面的SP来获取基于某个User 的Message:

    ALTER PROCEDURE [dbo].[Message_Select_By_User]
    (@UserID    VarChar(50))
    AS
    BEGIN   
        Select ID, UserID, [Message] From dbo.Messages Where UserID = @UserID
    END

    注:如何写成Select * From dbo.Messages Where UserID = @UserID, SqlDependency 将不能正常运行;同

    时Table的schema(dbo)也是必须的。

    我 们设计如下的界面来模拟:通过Add按钮,可以为选择的User创建新的Message,而下面的List将显示基于某个User(Foo)的 Message List。该列表的获取方式基于Lazy Loading的方式,如果在Cache中,则直接从Cache中获取,否则从Db中获取,并将获取的数据加入cache。

    image

    我们先定义了3个常量,分别表示:缓存message针对的User,获取Message list的stored procedure名称和Cache item的key。

    private const string UserName = "Foo";
    private const string MessageCachingProcedure = "Message_Select_By_User";
    private const string CacheKey = "__MessageOfFoo";

    我们通过一个Property来创建或获取我们的上面定义的SqlDependencyExpiration 对象

    private SqlDependencyExpiration CacheItemExpiration
    {
        get
        {
            IDictionary<string, object> parameters = new Dictionary<string, object>();
            parameters.Add("UserID", UserName);
            SqlDependencyExpiration expiration= new SqlDependencyExpiration(MessageCachingProcedure, parameters);
            expiration.Expired += delegate
            {
                MessageBox.Show("Cache has expired!");
            };

            return expiration;
        }
    }

    通过GetMessageByUser从数据库中获取基于某个User的Message List(使用了DAAB):

    private List<string> GetMessageByUser(string userName)
    {
        List<string> messageList = new List<string>();
        Database db = DatabaseFactory.CreateDatabase();
        DbCommand command = db.GetStoredProcCommand(MessageCachingProcedure);
        db.AddInParameter(command, "UserID", DbType.String, userName);
        IDataReader reader = db.ExecuteReader(command);
        while (reader.Read())
        {
            messageList.Add(reader.GetString(2));
        }

        return messageList;
    }

    通 过GetMessages获取User(Foo)的Message List:首先通过CacheManager检测message list是否存在于Cache,如何不存在,调用上面的GetMessageByUser方法从database中获取Foo的message list。并将其加入Cache中,需要注意的是这里使用到了我们的SqlDependencyExpiration 对象。

    private List<string> GetMessages()
    {
        ICacheManager manager = CacheFactory.GetCacheManager();
        if (manager.GetData(CacheKey) == null)
        {
            manager.Add(CacheKey, GetMessageByUser(UserName), CacheItemPriority.Normal, null, this.CacheItemExpiration);
        }

        return manager.GetData(CacheKey) as List<string>;
    }

    由于在我们的例子中需要对DB进行数据操作,来检测数据的变换是否应用Cache的过期,我们需要想数据库中添加Message。我们通过下面的方式现在message的添加。

    private void CreateMessageEntry(string userName, string message)
    {
        Database db = DatabaseFactory.CreateDatabase();
        string insertSql = "INSERT INTO [dbo].[Messages]([UserID],[Message])VALUES(@userID, @message)";
        DbCommand command = db.GetSqlStringCommand(insertSql);
        db.AddInParameter(command, "userID", DbType.String, userName);
        db.AddInParameter(command, "message", DbType.String, message);
        db.ExecuteNonQuery(command);
    }

    我 们的Add按钮的实现如下:基于我们选择的Username和输入的message的内容向DB中添加Message,然后调用 GetMessages()方法获取基于用户Foo的Message列表。之所以要在两者之间将线程休眠1s,是为了上SqlDependency有足够 的时间结果从Database传过来的Query Notification,并触发OnChanged事件并执行相应的Event Handler,这样调用GetMessages时检测Cache才能检测到cache item已经过期了。

    private void buttonAdd_Click(object sender, EventArgs e)
    {
        this.CreateMessageEntry(this.comboBoxUserName.SelectedValue.ToString(), this.textBoxMessage.Text.Trim());
        Thread.Sleep(1000);
        this.listBoxMessage.DataSource = this.GetMessages();
    }

    由 于我们缓存了用户Foo的Message list,所以当我们为Foo创建Message的时候,下面的ListBox的列表能够及时更新,这表明我们的cache item已经过期了。而我们为其他的用户(Bar,Baz)创建Message的时候,cache item将不会过期,这一点我们可以通过弹出的MessageBox探测掉(expiration.Expired += delegate           MessageBox.Show("Cache has expired!");}; ),只有前者才会弹出下面的MessageBox:

    image

    注:由于SqlDependency建立在Service Broker之上的,所以我们必须将service Broker开关打开(默认使关闭的)。否则我们将出现下面的错误:

    image

    打开service Broker可以通过如下的T-SQL:ALTER DATABASE MyDb SET ENABLE_BROKER ;

     

    posted @ 2008-09-04 21:15 小No 阅读(294) | 评论 (0)编辑

    Server Application Error

    The server has encountered an error while loading an application during the processing of your request. Please refer to the event log for more detail information. Please contact the server administrator for assistance. 

    出现 DCOM 遇到错误“登录失败: 未知的用户名或错误密码。 ”并且无法登录到 .\IWAM_APJ006 上以运行服务器


     

    解决IIS的Server Application Error办法2007-12-14 00:36 A.M.Server Application Error
    The server has encountered an error while loading an application during the processing of your request. Please refer to the event log for more detail information. Please contact the server administrator for assistance.


    访问IIS客户端出现如上错信息提示,

    在网上查了查解决方案如下:

    1。右键我的电脑--管理--本地用户和组,给IUSR_机器名和IWAM_机器名两个用户设置密码,要一样。

    2。开始--运行--打cmd,
    然后cd D:InetpubAdminscripts(我的系统在D盘),
    然后cscript.exe adsutil.vbs set w3svc/wamuserpass 你的密码,
    然后cscript.exe adsutil.vbs set w3svc/anonymoususerpass 你的密码

    看一下,行了没有?如果还不行,那么
    cscript.exe synciwam.vbs -v,
    然后iisreset。

    据说就可以了,但是到最后一部提示8004e00f的错误,此错误是MSDTC服务不正常造成的,解决方法:

    首先进入组件服务,查看组件服务/计算机/我的电脑/COM+应用程序,结果报错“COM+ 无法与 Microsoft 分布式事务协调程序交谈”,无法查看里面的对象。
    2、进入事件查看器,发现msdtc服务没有正常启动。
    3、删除注册表中的键:
    ? HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesMSDTC
    ? HKEY_LOCAL_MACHINESOFTWAREMicrosoftMSDTC
    ? HKEY_CLASSES_ROOTCID
    4、停止MSDTC服务:net stop msdtc
    5、卸载MSDTC服务:msdtc -uninstall
    6、重新安装MSDTC服务:msdtc -install
    7、确认在事件查看器中msdtc服务已经正常启动[这步很关键,如果没有,重新启动下电脑看看]
    8、重新设置IIS的IWAM账号密码。[在计算机管理中的用户管理里]
    9、同步IIS metabase中IWAM_MYSERVER的密码,在CMD中:c:inetputadminscripts>adsutil set w3svc/wamuserpass "yourpassword"
    10、同步COM+应用程序所用的IWAM_MYSERVER密码,在CMD中:c:inetputadminscripts>cscript synciwam.vbs -v

    到这部分网上大部分都说可以了,但是我这里虽然没有8004e00f的错误提示了,但是访问页面Server Application Error 错误依旧,最后终于找到了解决方法如下:

    解决办法:
    [1]:
    检查你的DTC服务(全名:Distributed Transaction Coordinator)是否可以正常启动,

    如果正常的话请你跳过此步骤;如果出错,无法正常启动,请在开始菜单的运行中 运行:msdtc -resetlog 以创建日志文件。重起机器,检查IIS是否可以正常使用,若不行继续。

    [2]:
    在CMD下执行以下命令:
    cd %windir%\system32\inetsrv

    rundll32 wamreg.dll, CreateIISPackage

    regsvr32 asptxn.dll

    (到这里我就可以用了,不用重启的)

    OK,ASP页面一切正常了@!~~~^_^

    Server Application Error
    The server has encountered an error while loading an application during the processing of your request.Please refer to the event log for more detail information.Please contact the server administrator for assistance.
    方法 1:在用户管理器或用户和组中更改密码,使其与 IIS 元数据库密码匹配
    1. 在“命令”窗口中,找到 Adsutil.vbs 文件所在的文件夹。使用 Adsutil.vbs 工具从 IIS 元数据库获得 IWAM 和 IUSR 帐户的密码。
    2. 若要在 Windows NT 中更改 IUSR 和/或 IWAM 密码,请按照下列步骤操作:

    a. 在开始菜单上,指向程序,指向管理工具,然后单击域用户管理器。在“域用户管理器”中,可以更改所有 Windows NT 用户帐户和组的帐户信息。
    b. 双击 IUSR_计算机名 和/或 IWAM_计算机名 用户,然后修改密码,使其反映您在步骤 1 中获得的 IIS 元数据库密码。
    若要在 Windows 2000 中更改 IUSR 和/或 IWAM 密码,请按照下列步骤操作: a. 在开始菜单上,指向程序,指向管理工具,然后单击计算机管理。
    b. 在系统工具节点下,单击以展开“本地用户和组”和“用户”节点。在“用户”节点中,可以更改所有 Windows 2000 用户帐户和组的帐户信息。
    c. 右击 IUSR_计算机名 和/或 IWAM_计算机名 帐户,然后单击设置密码。
    d. 修改密码,使其反映您在步骤 1 中获得的 IIS 元数据库密码。

    3. 浏览返回错误信息的 ASP 页,检查问题是否已解决。

    方法 2:更改 IIS 元数据库,使其与 IUSR 和/或 IWAM 密码匹配
    1. 若要在 Windows NT 中更改 IUSR 和/或 IWAM 密码,请按照下列步骤操作:

    a. 在开始菜单上,指向程序,指向管理工具,然后单击域用户管理器。在“域用户管理器”中,可以更改所有 Windows NT 用户帐户和组的帐户信息。
    b. 双击 IUSR_计算机名 和/或 IWAM_计算机名 帐户,然后键入新密码。
    若要在 Windows 2000 中更改 IUSR 和/或 IWAM 密码,请按照下列步骤操作: a. 在开始菜单上,指向程序,指向管理工具,然后单击计算机管理。
    b. 在系统工具节点下,单击以展开“本地用户和组”和“用户”节点。在“用户”节点中,可以更改所有 Windows 2000 用户帐户和组的帐户信息。
    c. 右击 IUSR_计算机名 和或 IWAM_计算机名 帐户,然后单击设置密码。键入新密码。

    2. 在“命令”窗口中,找到 Adsutil.vbs 文件所在的文件夹。使用 Adsutil.vbs 实用工具为 IIS 配置数据库中的 IWAM 和 IUSR 帐户设置密码。
    3. 浏览返回错误信息的 ASP 页,检查问题是否已解决。
    功能 语法
    获取 IUSR 帐户密码 cscript.exe adsutil.vbs get w3svc/anonymoususerpass
    获取 IWAM 帐户密码 cscript.exe adsutil.vbs get w3svc/wamuserpass
    设置 IUSR 帐户密码 cscript.exe adsutil.vbs set w3svc/anonymoususerpass "password"
    设置 IWAM 帐户密码 cscript.exe adsutil.vbs set w3svc/wamuserpass "password"

    注意:在 Windows NT 4.0 中尝试获取密码时,密码显示为明文;但在 Windows 2000 中,密码显示为星号。若要在 Windows 2000 中也让密码显示为明文,必须修改 Adsutil.vbs,使它显示明码。为此,请按照下列步骤操作: 1. 在“记事本”中,打开 Adsutil.vbs。
    2. 在“编辑”菜单上,单击查找,键入 IsSecureProperty = True,然后单击查找下一个。
    3. 将“IsSecureProperty = True”更改为“IsSecureProperty = False”。
    4. 保存对 Adsutil.vbs 所做的更改,然后关闭“记事本”。

    更改 MTS 或组件服务中的密码
    Windows 2000/XP/2003
    IIS 5.0 提供了 Synciwam.vbs 文件,以便更新在进程外运行的所有 IIS COM+ 应用程序包的启动标识。Synciwam.vbs 脚本位于 <驱动器>\Inetpub\AdminScripts 文件夹中。您可以使用 CScript 或 WScript 运行 Synciwam.vbs。

    若要使用 Synciwam.vbs,请在命令提示符处键入下面的命令:
    cscript.exe synciwam.vbs -v
    为使所有更改生效,您可能需要重新启动 IIS。若要重新启动 IIS,请在开始菜单上,单击运行,键入 iisreset,然后单击确定。

    注意:
    当COM+损坏时会出现以下现像

    在最后的cscript c:\inetpub\adminscripts\synciwam.vbs -v的时候还出现
    Error:1AD:ActiveX部件不能创建对象
    或通过运行MMC能添加组件服务但是一打开计算机就自动关闭或出错
    解决方法就要重新安装COM+
    一开始是说,COM+错误

    查看事件日志:
    出现某种状态,表示此 COM+ 应用程序处于不稳定状态或运行不正常。声明失败: SUCCEEDED(hr)

    服务器应用程序 ID: {02D4B3F1-FD88-11D1-960D-00805FC79235}
    服务器应用程序实例 ID:
    {6615E3FE-D159-48B5-BB65-D6B00778E75F}

    这是微软针对2000系统的解决方法:
    1.把%WinDir%\System32\Clbcatq.dll删除或改名
    2.重启一下
    3.进入注册表删除HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\COM3整支(注意备份)
    4.运行CMD,打CD %WinDir%回车
    5.打rmdir /s Registration回车
    6.如果你打过MS04-012补丁请重装一下
    7.进入控制面板,点击添加/删除Windows组件
    8.重新安装COM+
    解决方法如下:

    1。右键我的电脑--管理--本地用户和组,给IUSR_机器名和IWAM_机器名两个用户设置密码,要一样。

    2。开始--运行--输入cmd,
    然后cd c:\Inetpub\AdminScripts
    然后cscript.exe adsutil.vbs set w3svc/wamuserpass 你的密码,
    然后cscript.exe adsutil.vbs set w3svc/anonymoususerpass 你的密码

    看一下,行了没有?如果还不行,那么
    cscript.exe synciwam.vbs -v,
    然后iisreset

    Server Application Error续,8004EOOF错误

    发现运行C:\Inetpub\AdminScripts\synciwam.vbs时报8004EOOF错误,晕死,网上搜索了下,发现是

    MSDTC的问题: msdtc服务没有正常启动。 找到原因就好办啦^_^

    Step1

    删除注册表中的键:

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSDTC

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSDTC

    HKEY_CLASSES_ROOT\CID

    Step2

    停止 MSDTC服务:net stop msdtc

    Step3

    卸载MSDTC服务:msdtc -uninstall

    Step4

    重新安装MSDTC服务:

    msdtc -install

    然后再按照原来的解决Server Application Error的方法就可以了

    如果还不行的话,这时把IIS卸掉,重新安装就可以了啊


     

    未能访问 IIS 元数据库

    KB: http://support.microsoft.com/?kbid=267904

    如果是ASP 2.0就用  aspnet_regiis - ga <WindowsUserAccount>

    应该是 aspnet_regiis -ga IWAM_Machinename

    未能创建 Mutex  

    解决未能创建Mutex的问题 1 如果你还开着VS2005,关掉。2 到ASP.NET的临时目录下面<Windows dir>\Microsoft.Net\Framework\v2.0<extra numbers>\Temporary ASpNET pages3 删除你的项目的那个目录(或者都删除也行)4 重启IIS(如果在命令行下输入 iisreset)5 先打开IE访问你的项目6 然后再打开VS2005

    未将对象引用设置到对象的实例 System.Web.Hosting.ISAPIWorkerRequestInProc.GetServerVariable

    http://dev.communityserver.com/forums/p/474748/531732.aspx

    "aspnet_regiis -i" did the trick

     解决:服务器无法加载应用程序 '/LM/W3SVC'。错误是 '找不到指定的元数据'。

    http://blog.csdn.net/wangshangy/archive/2007/03/20/1534639.aspx

    解决办法:
                    [1]:
                    检查你的DTC服务(全名:Distributed Transaction Coordinator)是否可以正常启动,如果正常的话

                    请你跳过此步骤;如果出错,无法正常启动,请在开始菜单的运行中 运行:msdtc -resetlog  

                    以创建 日志文件。
                   
                    如果运行这个命令没出错 请跳过下面这行字。

                    如果运行这个命令出错请转到本文的下半部分的这个地方开始看。(==== 以下部分是网上重新找的资料 (如果执行上面步骤仍然不行,请继续) ==)

                    重起机器,检查IIS是否可以正常使用,若不行继续。

                    [2]:
                    在CMD下执行以下命令:
                    cd %windir%\system32\inetsrv 

                    rundll32 wamreg.dll, CreateIISPackage 

                    regsvr32 asptxn.dll

                    重起机器,我的问题到这步已经可以完美解决!

    至此,终于解决IIS报错的问题,,有点乱,但有时间整理问题解决的过程。

     

    综合分析上面的错误表现我们可以看出,主要是由于IWAM账号(在我的计算机即是IWAM_MYSERVER账号)的密码错误造成了HTTP 500内部错误。

     

    在详细分析HTTP500内部错误产生的原因之前,先对IWAM账号进行一下简要的介绍:IWAM账号是安装IIS5时系统自动建立的一个内置账号,主要用于启动进程之外的应用程序的Internet信息服务。IWAM账号的名字会根据每台计算机NETBIOS名字的不同而有所不同,通用的格式是IWAM_MACHINE,即由“IWAM”前缀、连接线“_”加上计算机的NETBIOS名字组成。我的计算机的NETBIOS名字是MYSERVER,因此我的计算机上IWAM账号的名字就是IWAM_MYSERVER,这一点与IIS匿名账号ISUR_MACHINE的命名方式非常相似。

     

    IWAM账号建立后被Active DirectoryIIS metabase数据库和COM+应用程序三方共同使用,账号密码被三方分别保存,并由操作系统负责这三方保存的IWAM密码的同步工作。按常理说,由操作系统负责的工作我们大可放心,不必担心出错,但不知是BUG还是其它什么原因,系统的对IWAM账号的密码同步工作有时会失败,使三方IWAM账号所用密码不统一。当IISCOM+应用程序使用错误IWAM的密码登录系统,启动IIS Out-Of-Process Pooled Applications时,系统会因密码错误而拒绝这一请求,导致IIS Out-Of-Process Pooled Applications启动失败,也就是我们在ID10004错误事件中看到的“不能运行服务器{3D14228D-FBE1-11D0-995D-00C04FD919C1} ”(这里{3D14228D-FBE1-11D0-995D-00C04FD919C1} IIS Out-Of-Process Pooled ApplicationsKEY),不能转入IIS5应用程序,HTTP 500内部错误就这样产生了。

     

     

     

    三、解决办法:

     

    1、重设IWAM密码

     

    打开我的电脑"管理",切换到"本地用户和组",单击"用户"选中"IWAM_computer_name"用户,右击选择"设置密码",在跳出的重设密码对方框中给IWAM_computer_name设置新的密码,这儿我们设置成"rock2006"(没有引号的),确定,等待密码修改成功。

     

    2、同步IIS metabaseIWAM_computer_name账号的密码

     

    可能因为这项改动太敏感和重要,微软并没有为我们修改IIS metabaseIWAM_computer_name账号密码提供一个显式的用户接口,只随IIS5提供了一个管理脚本adsutil.vbs,这个脚本位于C:\inetpub\AdminScripts子目录下(位置可能会因你安装IIS5时设置的不同而有所变动)

     

    adsutil.vbs脚本功能强大,参数非常多且用法复杂,这里只提供使用这个脚本修改IWAM_computer_name账号密码的方法:

     

    进入在cmd下进入C:\inetpub\AdminScripts

    cd C:\inetpub\AdminScripts

    C:\inetpub\AdminScripts>adsutil SET w3svc/WAMUserPass Password "rock2006"

     

    修改成功后,系统会有如下提示:

     

    WAMUserPass                     : (STRING) "**********"

     

    3、同步COM+应用程序所用的IWAM_computer_name的密码

     

    同步COM+应用程序所用的IWAM_computer_name的密码,我们使用组件服务MMC管理单元。

     

    (1)、打开控制面板,进入管理工具,找到“组件服务”->“计算机”->“我的电脑”->COM+应用程序”->Out-Of-Process Pooled Applications”,右击“Out-Of-Process Pooled Applications->“属性”。

     

    (2)、切换到“Out-Of-Process Pooled Applications”属性对话框的“标志”选项卡。“此应用程序在下列账户下运行”选择中“此用户”会被选中,用户名是“IWAM_computer_name”。这些都是缺省的,不必改动。在下面的“密码”和“确认密码”文本框内输入正确的密码“rock2006”,确定退出。

     

    (3)、系统如果提示“应用程序被一个以上的外部产品创建。你确定要被这些产品支持吗?”时确定即可。

     

    如果我们在IIS中将其它一些Web的“应用程序保护”设置为“高(独立的),那么这个WEB所使用的COM+应用程序的IWAM账号密码也需要同步。重复(1)-(3)步,同步其它相应Out of process applicationIWAM账号密码。

    posted @ 2008-08-01 16:51 小No 阅读(147) | 评论 (0)编辑