工作九年了,网站相关的开发工作也干了八年多。负责带领团队也好几年了。面试和带领刚工作的人也不少了。其中的优秀者不少,但是大多数都存在下面提到的几个认识误区。把这些问题提出来,希望对刚参加工作没有多久的程序员们有所帮助,少走弯路。
公司招你进来,其实最重要的就是看到你的工作能力和工作态度是可以接受的。
工作能力指你能满足他们的工作期望,或者在可接受的时间范围内,经过培训后,可以满足这个工作期望。
工作态度指你能有些做职员的基本素质。
这个道理应该所有人都清楚。但是到实际事情时候就经常犯迷糊。下面几点是经常会出问题的地方:
1、不经测试,Review,就认为自己工作完成了。
你的代码或者应用一旦被别人Review ,或者进行试用。这时候你代码的好坏,或者功能是否在各种场景下是否可用,都会影响你这个人在上级及同事眼里的可信任度。
代码书写的规范,性能的高质量,各种功能在各个场景都可用,则表示你这个人是完全可信的。下次上级给你分派任务的时候,就可以给你更多的自由度来发挥。长此以往,前途和钱途自然就随手可得。
反之,代码不规范,功能好些场景不可用。这只能让上级或同事觉得你不可信任。每次都需要处理你带来的这些问题,说恶心点就是你每次拉完大便都没擦屁股,每次都得你的同事和上级帮你擦屁股。数次都这样后,上级或同事下次跟你沟通的时候就会觉得你这个人不可信任,一件事情必须反复多次强调,总觉得你还会作出问题。你的信用已经非常危险了。
你在别人眼里的信用就这样被你慢慢透支了。透支到一定程度,走人吧。整个团队的效率会因为你而变慢(每个人跟你沟通的成本都会影响到他本人的产出),你不走人谁走人。
2、最短可接受的工作时限
你有没有统计过,公司分派给你一个工作时候,上级指定的这项工作计划做多久的预计,跟你自己的预计有多大差异?
如果你预计时间大于上级给的工作计划时间,同时上级没有增派人手进行相关工作。除了BT的领导外,那只有一种情况:上级对你的工作态度非常不满,认为你的薪水对应的工作能力不是这么点。
对于刚工作的,更多的是你表现出来的工作能力在公司的平均工作能力之下。同时公司觉得你对工作没有表现出足够的热情。 一个能力在平均水平下面,又缺乏工作激情的人,他的前途在那里??
如果这个人还没有表现出几个月后能达到平均水平之上的希望,为啥会留这样一个人呢?
3、工作能力不等于技术水平
我曾看到过有人抱怨说大公司的员工也不过是这技术水平, 这么简单的技术问题都不会。我自己早期也有这样想法,后来发现是不对的。
不论大公司还是小公司,要得是解决问题的工作能力。 我的曾经手下就有好几个技术水平很牛的,但是作出来的应用却一次次返工的。为啥,工作能力这些非技术因素他们做的很不好。
工作能力的非技术因素包括的很多: 责任心,表现就是对自己写出来的代码有一定要让人放心的责任; 沟通能力,一个典型的表现就是需求不理解或者需求不明时,及时得跟相关人沟通,而不是自己先按自己想法实现,造成代码写完后再返工的恶果等等。
技术水平低,但是解决问题能力强的,我也碰到过一些人。 工作的能力更重要的是这些非技术的工作能力,而不是技术水平。技术人员很容易技术水平高,但是非技术的工作能力差。 这是很糟糕的。
4、发展潜力,学习能力
公司使用的技术不可能一直不变,一直不变的公司只能慢慢被市场淘汰。这就要求员工能不断的学习新的知识,并应用到工作中来。
要想不会出现几年后,自己发现跳槽找个工作都没人要,赶快学习吧。
坚持,是一个人最难做到的。 但是不坚持,那就等着灭亡吧。
5、笨鸟先飞
一个人,在公司,如果工作能力在平均线以下, 加班吧, 不要有任何幻想。
最可怕的是自己没这个意识, 自认为自己技术水平很牛, 但是解决问题的工作能力却在平均水平线以下, 眼高手低 , 这样的人, 公司是不能留的。
6、承诺到的事情一定要做到,不要找理由
一件事情没有被做完,想找理由能找很多的。既然你承诺了某个时间点前完成,就不要再找各种理由推脱。
公司同事和上级虽然可能这次接受了你的理由,但是下次呢, 慢慢的就会让你的上级,同事觉得你是一个喜欢推托的人。 感觉你干事是非常不可靠的。不知道那次就会不完成,下次谁敢再找你干事?
可能很多人在看到我这篇博客的时候,觉得我写的很刻薄,好像都是从公司的角度欺压技术人员。很没有人情味。
只要你不是公司的董事, 你永远是被剥削者,公司的目的就是利润最大化,这是公司存活的根本目的。作为普通的职员,要有所为的白领意识,其实就是被剥削意识。这是个适者生存的生态圈,不适用的人只能被淘汰。
实际的公司其实有很多人情味在里面,或者同事和领导有些话不便于说出口。 这也就造成了一些技术人员被开除,还自以为如何如何? 都是没有这些意识造成的。我写这篇博客就是希望能增加技术人员的这些意识,不要犯了这些问题还自己不知道。
【原文地址】A Live Mesh Moment
【原文发表日期】15 July 08 09:35
当最近我在南非的Kruger国家公园附近的灌木丛中游玩时,我发现了Live Mesh一个绝妙的用途……在观赏了一整天精彩的大型游戏之后,我拍了一大堆的照片,希望给大家展示我的劳动成果。
夜里,回到了我的临时往处后,我匆匆地连上了网络,只有非常低的带宽的无线网络可以使用。因此我通过live mesh分享我的照片,很快地我那些宝贵的照片就在云端(Cloud)创建了备份。在照片上传时,我不由在想,我是多么地希望能够将我的经历与我的妻儿们分享啊,她们现在正在半个地球之外的地方熟睡呢!
如果能让厨房里的手提显示我最新的照片,我想那会很有趣的。于是我“连接”到我妻子的电脑上,并成功地获得了远在10000英里之外的终端服务会话。
完全就如同我正在坐在我们的厨房里的手提的键盘前面一样,即使是非常糟糕的网络,我依然很快地更改了她的屏保,将其指向了包含我的精彩照片的那个新的live mesh的文件夹。
当她们在早上起来后,我五岁的儿子是第一个注意到厨房里的手提上的长颈鹿和狮子的人!这就是用live mesh分享体验的魔力!
在整个旅途中,只要我能获取一丁点儿的网络连接,一批新的照片就会上传上去。当我到达微软的约翰内斯堡的办公室时,我的家庭已经完整地体验了我的旅程。
感谢Mesh。
上周收到样书了,全名叫做《黑客大曝光:Web应用安全机密与解决方案(第2版)》,原版的英文名为《Hacking Exposed Web Applications, 2nd Ed》。
关于这本书,更多详细的信息在 http://www.china-pub.com/39980, 目前还处于“预订”的状态。
在Amazon上,也可以看到本书英文原版的评价和详细信息,链接请点此处。
要感谢的人很多,列名字的时候,真是诚惶诚恐,生怕族繁不及备载,少列了任何一个名字,都是很不好的事情。因此,先容许我,以我最大的诚意,一并先说声,谢谢你们。
以下以“讲故事”的方法,向提供帮助的诸位,表示最真挚的感谢。因为"感谢CCTV,感谢DDTV,感谢EETV"这样的套话,恐怕听众都厌烦了,不适合让他们记住您的名字。
之所以翻译这本书,最开始的渊源来自于博客堂。2007年初的博客堂年会,见到了电子工业出版社博文视点的郭立女士,李冰编辑和卢帆编辑。且先略过诸位编辑都很pp不表,继续正题,说书的故事。会后不久,李冰编辑问我有没有兴趣翻译这本书的时候,我本人从大学开始就对网络安全一直颇感兴趣。而在微软从事的第一个项目,刚好就是个web的企业级应用,也负责和参与了安全测试的工作。即使我现在从事的是搜索引擎的开发工作,不那么直接的参与安全方面的工作了,也依然对安全领域保持着很大的兴趣。总而言之,我对这本书很有兴趣。感谢博客堂和开心老大组织的年会。感谢博文视点的郭立总经理和李冰编辑。
后来找到王炜老兄一起做这个事情。他更是个网络安全的狂热爱好者。因为他在希格玛大厦实习过,所以我们认识。刚开始联系的时候,他已经回到四川了,现在,我们已经是同事了,以后在希格玛大厦,会经常碰头的。谢谢王炜,更为正式的说法应该是,谢谢王炜博士,没有你的努力和认真,我压根就无法想象这本书现在可以摆在案前。向辛勤工作一丝不苟的的许艳编辑致谢,向校阅的罗代升教授致谢。
说来也很巧合,本书的作者Caleb Sima,我2006年在西雅图参加Bluehat的时候还见过,听过他的精彩的讲座,记忆犹新。要感谢Caleb和其他的两位作者Joel Scambray和Mike Shema ,对自己多年专业经验的分享,编写了这样一本在web安全领域极具学习和参考价值的书。甚至在今年,因为此书还有过“美丽的误会”,我在live space的blog上有详细的记录。
向提供过无私帮助的wingc老兄致谢。
其实最最重要的事情是,希望书的翻译质量,对得住读者的钱包。而水平所限,错误可能在所难免,还望各位指正和拍砖。

很久没写博客了,最近非常忙,大概要一直忙到8月底才会好点。但一直关注着ASP.NET MVC的发展,Scott Guthrie,Phil Haack, Scott Hanselman,Stephen Walther (他的ASP.NET MVC Tips系列非常值得一读)等的博客总会在有空的时间阅读一下。
这个版本是个非常值得关注的版本,Scott Guthrie在他的博客中对其中的功能做了简短的介绍,Scott Hanselman对其中新加的AJAX功能做了一个简单的示范:
http://www.hanselman.com/blog/ASPNETMVCPreview4UsingAjaxAndAjaxForm.aspx
下面这个网页有该版本的安装程序以及源码的下载链接:
http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=15389
WSS 3.0与MOSS 2007发布了在SP1之后的又一个重要更新:Infrastructure Update。
WSS 3.0 Infrastructure Update Download
MOSS 2007 Infrastructure Update Download
容我说点陈年往事。 去年的软件产业的数据,尽可能直观的说说,欢迎大家指正。
去年软件产业的总收入5800亿,增长20.8%。就相当于软件产业的GDP是5800亿,占中国总GDP的1/40。假设总共从业人数为140万(大概就是这个数),所以软件行业的人均GDP,就是41万元,是人均GDP的22倍。
按照记者的口气是,从某某大会获悉,2007年软件产业产值已经达5800亿。实际上根本不用去开会,这些数据都能第一时间看到。去年的数据,在信息产业部的网站上,2008年2月3日就出来了,链接见本文最后。
我第一时间看了,幸好当时没写blog,否则就闹笑话了。我把“教训”总结一下。 我当时拿excel加了一下,整整11600亿,1.16万亿啊,当时是有点吃惊了,差不多就是中国总GDP的1/20了。 最近终于从这个错误中反应过来了。你们可以看看,第一列是“软件业务收入”,实际上这是后面的总计。后面的“软件产品收入”“系统集成收入”都是属于分类的统计了。不过这几列,都没有任何直观上的区分,容易弄混,还算情有可原。
回到正题,软件产业在地域上,相当的集中。看看2007年的数据,北京占了21.8%,广东16.9%,江苏,14.35%,上海8.5%。 北京和我想象的差不多。江苏比想象的多,上海比想象的少,不太明白其中的原因。
以下摘录了2007年的前12名,单位亿元。合计 5800.1 北京市 1263.1 广东省 981.2 江苏省 832.4 上海市 494 浙江省 354.3 山东省 302.9 四川省 240.2 辽宁省 234.1 福建省 220 陕西省 144.8 吉林省 93 湖南省 78
其实数据仅仅是问问题的起点。比如,和其他国家横向的比较也很有意义。可惜我还没有找到太多详细的数据,其实本文有点想抛砖引玉的意思,欢迎更多的数据和分析。
具体数据请参照 http://www.miit.gov.cn/art/2008/02/03/art_5104_47694.html
更多的相关数据 http://www.miit.gov.cn/col/col5104/index.html
[原文发表地址]Composite Application Guidance for WPF
[原文发表时间]Tuesday, July 15, 2008 12:20 PM
我们尽可能地定期更新我们的指导库(Guidance Library)的内容,以满足架构师和应用程序开发人员对微软产品和技术的指导的需求。这些指导将帮助大家了解如何更好地将微软的各种产品和技术应用到自己的应用程序中以及如何应对各种技术挑战。
最近,我们发布了一个最新版本的指导库 – WPF复合应用 指导(Composite Application Guidance for WPF, CAB)。
这个指导包旨在帮助开发人员更快速开发企业级的WPF (Windows Presentation Foundation)客户端程序。对于如何开发一个具有良好扩展性的WPF复合客户端程序(复合应用程序松耦合,独立的可扩展的组件在整个程序中协同工作),这个指导包为开发人员提供了从设计到开发的详细步骤指导。用这种方法构建的解决方案能充分发挥WPF的巨大优势,程序将会具有良好的可维护性、可测试性,并且在开发过程中还可划分为不同模块分发由不同小组进行开发。
CAB的产生受到了诸如Dell 呼叫中心等应用程序的启发,这类程序主要由呼叫中心代表使用来提供以任务为核心的用户体验。CAB将减少程序之间的复制粘贴的必要,而且它也帮助降低平均呼叫时间,并提升销售过程的效率和效果。
这个指导包主要涵盖了以下几个重点方面:
· 模块化:这个复合应用程序库提供了更好的模块化的支持,允许您将业务逻辑、可视化组件、基础架构组件、表示层或控制器组件以及其他应用程序需要的对象在不同的模块中实现。开发人员能够轻松地分别独立创建UI或业务逻辑模块。
· 复合用户界面:这个复合应用程序库提升了用户界面的复合能力,允许您通过多个不同的松耦合的可视化组件来实现自己的可视化组件,这些组件通常被称为视图,并可能分布于不同的模块中。这个可视化组件能够展示来自多个后端系统的内容,而用户看到的则是无缝的单个程序。
在这个指导包中您将看到一个参考实现、一个WPF复合应用程序库、快速开始的指导、动手实验以及超过300页的文档,包括UI设计器指导和How-to等文档。
您可以通过MSDN 这里,或者通过CodePlex 这里来获取这个指导包。目前已经有很多的用户使用这个指导包来构建他们自己的应用程序,包括会计公司、大型银行以及政府机构等等。
Namaste!
【原文地址】ASP.NET MVC Preview 4 Release (Part 1)
【原文发表日期】 Monday, July 14, 2008 2:18 AM
ASP.NET MVC开发团队正处于完成崭新的“第四个预览版”的最后阶段,他们希望在本周稍后发布这个版本。第三个预览版着重于完善ASP.NET MVC中的许多底层的核心API和扩展点。从本周的第四个预览版开始,你将看到越来越多的建立于这些核心基础之上的,增加生产力的高层特性开始出现。
这个新的版本里有一堆新特性和功能,实际上其数目之多,我决定我需要2个帖子才能对它们全部论及,这第一个贴子将讨论第四个预览版中的缓存(Caching),错误处理(Error Handling)和安全(Security)新特性,以及一些测试方面的改进,我下一个贴子将讨论这个版本中新加的AJAX特性。
Action过滤器属性(Filter Attributes)是ASP.NET MVC中一个非常有用的扩展功能,这个东西最初是在第二个预览版中加入的,允许你在对MVC控制器的请求中注入拦截代码,在 Controller和它的Action方法执行的前后执行,这可以促成一些非常棒的封装场景,在其中,你能以一种非常干净的,声明的方式轻松地封装和重用功能。
下面是一个极其简单的例子,ScottGuLog过滤器,我可以用它来记录在请求的执行过程中抛出的异常的细节。实现一个定制的过滤器类非常容易,只要继承自ActionFilterAttribute类型,覆盖其中的适当方法,在Controller的Action方法调用之前或之后,或者在ActionResult处理进回复之前或之后运行代码。
在ASP.NET MVC Controller中使用过滤器也是非常容易的,只要在Action方法上将其声明为一个属性,或者在Controller类本身之上声明即可(在这个情形下,它将运用于Controller中所有的Action方法):
在上面,你可以看到应用了的2个过滤器的例子,我表示要将“ScottGuLog”运用于“About”这个Action方法,而将“HandleError”过滤器运用于HomeController的所有Action方法之上。
ASP.NET MVC的以前几个预览版本早就开启了这个过滤器扩展性,但并没有发布预制的过滤器,这第四个版本包含了几个有用的过滤器,可以用来处理输出缓存,错误处理以及安全的场景。
[OutputCache]过滤器提供了一个简易的方式,将ASP.NET MVC与ASP.NET的输出缓存功能相结合(在ASP.NET MVC第三个预览版中,你要编写代码才能实现这个功能)。
想试验一下的话,修改HomeController(是由VS ASP.NET MVC项目模板生成的)中的Index Action方法的Message值来显示当前时间:
在运行这个应用时,每次刷新页面,你都会看到时间戳更新:
我们可以在我们的Action方法上加[OutputCache]属性来给这个URL启用输出缓存,我们将使用下面的声明来配置缓存回复10秒钟:
现在,当你点击刷新时,你会看到时间戳每10秒钟才更新一次。这是因为action方法每10秒钟才会被调用一次,其他时间的所有请求都是从ASP.NET输出缓存中供应的(意味着不用运行什么代码,所以请求的回复超快)。
除了支持时间间隔外,OutputCache属性还支持标准的 ASP.NET 输出缓存变化选项(随参数,头内容,内容编码以及定制逻辑而变化)。例如,下面的例子会根据PageIndex查询字符串参数的值保存不同的页面缓存版本,然后会根据进来的URL的查询字符串值自动显示正确的版本:
你还可以结合ASP.NET的数据库缓存失效功能,该功能允许你在URL依赖的数据库被修改后自动导致缓存失效(小技巧:实现这个功能的最佳方案是在你的web.config中配置一个CacheProfile节,然后在OutputCache属性中配置指向该节点)。
[HandleError]过滤器提供了一种声明的方式,来在一个Controller或一个Action方法上表示,如果在处理一个ASP.NET MVC请求中发生错误的话,应该显示一个友好的错误回复。
要试验一下的话,在项目中加一个新的TestController,实现一个action方法,在其中象下面这样抛出一个异常:
在默认情形下,如果将浏览器指向这个URL的话,它会给远程用户显示一个默认的ASP.NET错误网页(除非你去web.config文件中配置了<customErrors>节):
我们可以在我们的Controller类或其中的Action方法上加一个[HandleError]属性,来改变要显示的HTML错误,而显示对终端用户比较友好的信息:
HandleError过滤器会捕捉住所有的异常(包括处理视图模板时抛出的错误),在出错时显示一个定制的Error视图回复。在默认情形下,它试图在你的项目中寻找一个名为“Error”的视图模板来生成回复。你可以将“Error”视图置于同个Controller相应的视图的目录之中(例如,上面的TestController的\Views\Test目录),也可以置于\Views\Shared文件夹中(系统会先找一个特定于控制器的出错视图,如果没找到的话,会在Shared文件夹中寻找,该文件夹包含了为所有控制器所共享的视图)。
从第四个预览版开始,在你创建新的ASP.NET MVC项目时,Visual Studio现在会自动为你在\Views\Shared文件夹中加一个默认的“Error”视图模板:
在我们的TestController类上加[HandleError]属性后,在默认情形下,它会给远程用户显示一个象下面这样的HTML错误页面(注意,它使用了项目的母板页,这样就将错误信息集成进了站点之中)。很明显地,你可以去定制这个Error视图模板,显示你想要的任何HTML或者更加友好的错误信息,下面只不过是随该版本而来的原装的信息:
为帮助开发人员,在本地浏览应用时,Visual Studio中由新的项目模板提供的默认的Error视图模板还会显示额外的错误堆栈跟踪信息:
你可以在Error视图模板中将代码删除来将其关闭,或者也可以在你的web.config文件中将<customErrors>设成“Off”。
在默认情形下,[HandleError]过滤器将捕捉和处理请求中抛出的所有异常。你也可以在[HandleError]属性上指定 "ExceptionType"和"View"属性来指定你感兴趣的特定异常类型,以及指定定制的错误视图:
在上面的代码中,我选择为SqlException和NullReferenceException异常显示定制的错误视图,所有其它的异常则将使用默认的“Error”视图模板。
[Authorize]过滤器提供了一种声明的方式来控制对Controller或Action方法的访问权限,它允许你表示用户必须已经登录,或者要求他们必须是某个特定的用户或是某个特定的安全角色才能访问。这个过滤器可以用于任何类型的认证方式(包括基于Windows以及Forms的认证),还提供了自动将匿名用户转向到登录页面的支持。
要试验一下的话,在Visual Studio中给默认生成的HomeController中的“About” action方法加一个[Authorize]过滤器:
象上面这样声明[Authorize]属性表示用户必须已经登录进网站才能请求“About” action。如果还没登录的用户试图访问/Home/About URL的话,他们会无法访问该页。如果web应用是配置成使用基于Windows的认证的话,ASP.NET会自动使用他们的Windows登录身份来认证用户,如果成功的话,就会允许他们访问。如果web应用是配置成使用基于Forms的认证的话,[Authorize]会自动地将用户转向到登录页面以作认证(之后他们就能访问了):
[Authorize]属性也允许你将访问权限只授予特定的用户或角色。例如,如果我要将"About" action的访问权限只限于我自己和Bill Gates的话,我可以这么写:
一般来说,除了无关紧要的应用外,你不该在代码中硬写用户名字,一般地,你应该使用象“角色”这样的比较高层次的概念来定义权限,然后另外将用户映射到角色上(例如,使用活动目录或数据库来储存这些映射)。[Authorize]属性通过使用“Roles”属性,极大地方便了对Controllers和Actions的访问的控制:
[Authorize]属性并不依赖于任何特定的用户身份或角色管理机制,它只用ASP.NET的"User"对象,该对象是可扩展的,允许使用任何身份系统。
我在上面提到了[Authorize]属性可用于任何认证或用户身份管理系统,你可以编写或使用你想要的任何定制的登录UI或用户/密码管理系统。
但为助你起步,Visual Studio中的ASP.NET MVC项目模板现在包含了一个预制的“AccountController”类以及相关的登录视图,它们实现了表单认证成员系统,支持登录,退出,注册新用户,改变密码等。所有的视图模板和UI都可以轻松地定制,是独立于 AccountController 类或实现的:
Site.master模板在右上角也包括了UI,提供登录/退出功能,在使用基于表单的认证时,如果你目前还没认证的话,它会提示你登录:
在你通过认证后,它会显示一个欢迎信息,以及一个退出链接:
点击上面的Login链接,会将用户转到象下面这样的登录屏幕来做认证:
新用户可以点击注册链接来创建新的帐号:
错误处理和错误信息显示也是内置的:
加到新项目中的AccountController类使用了内置的ASP.NET Membership API来存储和管理用户凭证(Membership系统使用了提供器API,允许接入任何后台存储,ASP.NET包含了内置的Active Directory 和 SQL Server提供器)。如果你不想使用内置的Membership系统的话,你可以保留同样的AccountController action方法签名,视图模板,Forms认证ticket逻辑,只要替换掉AccountController类中的用户帐号逻辑就可以了。在下一个ASP.NET MVC预览版中,我们计划将AccountController和用户身份系统间的交互逻辑封装成一个接口,这将进一步方便你接入你自己的用户存储系统(而不必实现一个完整的membership提供器),以及方便你对它和AccountController进行单元测试。
我们的希望是,这给大家提供了一个很好的快速起步的方式,允许大家在创建一个新项目后,就有一个工作的end to end的安全系统。
在这第四个预览版的第一个贴子里要提到的最后一个改进是对Controller类所做的一些改进,这些改进将允许你更轻松地单元测试TempData集合,TempData 属性允许你保存你要持久到将来一个用户请求的数据,它的意义在于,只持续到下一个请求为止(之后就被去除了)。一般用于这样的MVC场景: 你想要进行一个客户端的重新定向来改变浏览器中的URL,然后想要一种简便的方式来保存临时的数据。
在以前的ASP.NET MVC预览版中,你需要mock对象才能测试TempData集合。在第四个预览版中,你不再需要mock或设置什么了,你现在可以在单元测试中,直接在Controller的TempData集合中添加和核实对象(例如,在调用控制器的一个action方法之前填充它的TempData属性,或者在action方法返回后核实action方法更新了TempData)。TempData集合的实际存储机制现在封装在单独的TempDataProvider属性中了。
希望上面的贴子内容对即将发布的ASP.NET MVC的第四个预览版中的若干新特性和变动提供了一个简单的介绍,下一个贴子将讨论新加的 AJAX 功能,并且示范如何利用它。
希望本文对你有所帮助,
Scott
在奥运会期间, IE 8 Beta 2将会发布,而且随着英文版的发布,中文版也会在第一波当中进行发布。
IE 8将会是Internet Explorer历史上最重要的一个版本发布,除了其带有中国传统的吉祥数字“8”以外,最主要的是其对标准的兼容性上得到了极高的增强,这对于网页开发人员来说,最大的便利就是不用再为每种浏览器(甚至某种浏览器的不同版本)开发不同的CSS来进行适应。以后网页开发人员只需要兼容W3C的标准即可,而不需要把过度的精力放在不同浏览器标准的相异性上。
发布时间在即,那么您的网站是否已经准备好了呢?
1) 兼容性考虑
目前的网站由于各种历史原因,可能针对不同的浏览器设置了不同的CSS文件。而针对IE 8,可能大部分网站尚没有做好准备。可能很多朋友知道,IE 8带有一个“切换IE 7模仿模式”的按钮,而且在Beta 1以及Beta 2期间,这个按钮是设置在默认选中状态。但是在IE 8正式发布的时候,该按钮默认将会是非选中状态,这就表示着如果一个网站没有做任何准备功课,在IE 8下将会以严格模式来常解析CSS。
前段时间,我与合作伙伴见面时,曾经特意使用IE 8 Beta 2的严格模式浏览过大部分合作伙伴的网页,都会出现或多或少的显示变形的问题,使得网站无法进行正确浏览。如果您的网站尚未做过IE 8的兼容性测试,建议您尽快下载IE 8的Beta 1,并且将其切换到IE 8严格模式,对您的网站进行浏览。
如果您发现问题,并且感觉在短期内无法修复,您也可以通过在页面当中添加Meta标签,在服务器端强制IE 8使用“IE 7模仿模式”,做法很简单:
a. 针对全站页面: 您可以修改Web服务器(如Apache/IIS/Resin等)的HTTP头信息,在其中增加以下指令: X-UA-Compatible: IE=EmulateIE7。这个是我个人强烈推荐的做法,在您无法进行全站测试的情况下,可以先使用此方式使IE 8的严格模式暂时失效。
b. 针对单独页面:如果您的网站大部分页面在IE 8严格模式下显示正常,只有个别页面出现问题,建议在出现问题的页面的页首,即Head标签内添加以下Meta标签:
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />。
更多信息,请参考: http://support.microsoft.com/kb/952030/
2) 制作Activity以及WebSlice
IE 8在Beta 1期间曝光了两个新特性,即Activity(活动)以及WebSlice(源剪辑),目前国内很多网站已经基于Activity以及WebSlice制作了相关的内容,在IE 8 Beta 2期间,您会发现更多的网站会发布这些实用的小工具。以下是目前已经对外发布的一些网站:
a. 淘宝:http://ie8.taobao.com
b. 网易:http://ie8.163.com
c. 百度:http://stock.baidu.com/ie8/ie8.html
d. 腾讯:http://labs.qq.com/e/49/
甚至包括.NET开发人员常去的博客园也已经发布了其最新文章的Web Slice,有兴趣的话可以使用IE 8 Beta 1来访问博客园的首页。另外,如果您也使用Firefox 3,您可以发现已经有人开发了面向Firefox 3的Activity以及WebSlice插件。
Activity的使用场景:您的网站提供一系列的服务,允许贵网站的用户通过在其它网站的主动操作来调用此服务。比如假设您是一个财经网站,提供查询股票/基金信息的服务,通过Activity,您可以让您的用户在其它网站上浏览股评信息时,不需要跳转到贵网站,即可以通过右键菜单调用贵网站的相应服务。如果感兴趣,可以下载Activity开发白皮书。
WebSlice的使用场景:您的网站提供一些实时性信息,比如新闻、股票信息等,而希望用户可以在不返回相应页面的时候,当内容发生改动时,即可以推送给最终用户,您可以选择WebSlice。而开发代价仅仅只是将页面当中的某一个标签内的“Class”元素设置为“hslice”这个特殊名称即可,详细信息请阅读WebSlice开发白皮书。
另外,在IE 8 Beta 2发布时,微软将会发布一个面向IE 8全新的Gallery网站,用以搜索各个网站开发的WebSlice/Activity等面向IE 8新特性的组件,并且提供最终用户评估/下载,如果您希望您开发的WebSlices/Activity能够得到用户的青睐,那么就从现在开始吧:早起的鸟儿有虫吃。 :)
3) 其它
IE 8 Beta 2发布时,还将会带来一系列的新特性,在前段时期,已经面向国内一些领先的网站进行过交流,很多合作伙伴都非常感兴趣,并且正在开发此上的服务,相信在奥运会期间大家会看到此类的成果(依据NDA协议,此类网站也已经从微软拿到了IE 8 Beta 2的早期内部版本)。微软也将会举办一系列的市场活动,用以推广我们的合作伙伴所开发的各种面向IE 8的新的服务。
IE 8 Beta 2即将发布,无论您是企业网站的网页设计人员,还是个人网站的站长,都需要尽快为IE 8做好准备。 希望本文对您有帮助。
【原文地址】Very Simple .NET Thumbnail Creation Code
【原文发表日期】10 July 08 09:15
当我在更新我的Ajax示例的时候,我需要为某个目录下的图片创建缩略图。可用的工具实在是多不胜数,不过我还是想分享一下我所使用的一段非常简单的代码。
这段程序会提取根目录下的所有jpg文件,为它们创建160*120的缩略图,并将图片拷贝到完整路径下。
namespace ThumbNailer { class Program { static void Main(string[] args) { string rootPath = @"C:\Users\brada\Desktop\ForDemo"; string thumbPath = Path.Combine(rootPath, "Thumb"); if (Directory.Exists(thumbPath)) DirectoryDelete(thumbPath); Directory.CreateDirectory(thumbPath); int imageNumber = 0; foreach (string s in Directory.GetFiles(rootPath, "*.jpg")) { imageNumber++; Console.WriteLine("{0}:{1}", imageNumber, s); Image i = Image.FromFile(s); Image thumb = i.GetThumbnailImage(160, 120, null, IntPtr.Zero); thumb.Save(Path.Combine(thumbPath, GetName(imageNumber))); } } static void DirectoryDelete(string directoryName) { foreach (string filename in Directory.GetFiles(directoryName)) { File.Delete(filename); } Directory.Delete(directoryName); } static string GetName(int imageNumber) { return String.Format("{0}.jpg", imageNumber); } } }
更新:有些人问我如何在ASP.NET中实现……Bertrand有一个完整得多的例子在此:
http://dotnetslackers.com/articles/aspnet/Generating-Image-Thumbnails-in-ASP-NET.aspx
http://weblogs.asp.net/bleroy/archive/2007/12/05/what-interpolationmode-and-compositingquality-to-use-when-generating-thumbnails-via-system-drawing.aspx
【原文地址】WPF Composite Application Guidance is Live
【原文发表日期】03 July 08 06:20
面向商业应用的一个非常通用的模式是“Composite Application Pattern”(组合应用模式)。在过去的几个月中,我们的P&P(Patterns & Practices)团队与业界的领导者与Microsoft的生产团队合作,为创建WPF composite application的创建推出了一个示例应用以及一个框架。
如果你正关注于创建一个面向商业的WPF应用,你真的应该查看一下这个……它包含了所有的文档、源码甚至是单元测试!
看一下它吧!WPF Composite Application指南
【原文地址】Great User Experience Example in a Business Application
【原文发表日期】07 July 08 08:00
DRN-TV与Billy Hollis进行了一次精彩的对话与演示,谈论了在WPF与Silverlight上开发的下一代商务应用。Billy与他的客户共同合作,提供了一个为临时工寻找合适的工作职位的平台。目前这个应用是创建在WPF上的,不过他们目前正在计划创建Silverlight的版本。请观看这个包含了完整演示内容的web cast。
这些是我觉得很酷的东西:
Billy, 我们都盼望着尝试一下实际的产品呢!
这里是一些屏幕截图:
![]()
最近家里的的项目有所变化,首先,吃的 - 据说公司原来是每天下午3点到3点05分供应时鲜水果,现在改为8小时供应。而且时不时还有免费晚餐,听说他们项目组的同事纷纷赞美 - 工作着是美丽的。。。
其次上下班时间不太正常 (什么时候都这样,所以不算什么变化),回到家里,电话也继续追到家里,晚上11点还和同事打电话,争论五道口一带是否真的还在堵车。 我掐指一算,不错,又到了 http://ditu.live.com 新版本上市的时间了。
这次新版本倒是有几个功能和大家的出行密切相关:
一个是“实时路况”,北京市的路况,随时都能看到 (这是上一次发布之后不少用户要求的功能):
![]()
另一个新功能,是"发送乘车路线到手机", 比如有朋友向你问路, 你可以很方便地把查到的乘车路线通过手机短信的形式发给这位朋友,不用口头转述或者手工输入短信。 而且这是免费的!
![]()
第三个功能,据说是可以把地图上任何一点的地址也发到任何手机中,不过我找了半天也没发现怎么使用这个功能。 哪位读者找到了,就在留言上告诉我一声。
发布了这几个广大用户喜闻乐见的功能,领导也很满意,为了迎接奥运,他们决定声东击西,围魏救赵,计划派若干基层团队成员(可带家属)浪漫欧洲N日游。
还会有新功能么? 有,据说还有一批很 cool 的功能要震撼登场 - 不过要等到这一届奥运之后,下一届奥运之前了。
一般来说,我们把报表分为两类,一类是ad-hoc的报表,用于实时查询,客户可以输入特定的参数,得到他们感兴趣的报表,还有一类是scheduling的报表,用于自动生成,一般包括daliy,monthly,quarterly和yearly的报表,这种定制类的报表,可以在指定的时间,生成到指定的目录,他们生成的内容也会提前定制,参数不可更改。一般在报表的需求定义中,客户都会要求报表能够做到自动生成,这也就是我们所说的第二类报表,有时候,客户还会要求能够在自动生成的同时,实现自动打印。下面我们来谈谈如何实现报表的自动生成以及自动打印。
首先来谈谈解决方案,由于RS提供web service式的调用,因此我们可以写一个remoting service或者windows service或者仅仅是一段程序,然后由job之类的调用,来实现报表的自动。在程序中,我们调用RS,来实现报表的生成。需要生成的报表列表,报表的参数(时间参数),导出文件的格式,我们定义在数据库里,解决方案简单的用图表来表现如下:
下面我们来谈具体的步骤
第一步:创建项目,添加web引用(C#项目),URL为http://localhost/ReportServer/ReportService.asmx
![]()
第二步,取参数以及定义其他的参数。
参数表的内容为:
ReportName PeriodType PromptName1 Prompttype1 Format
SupplierD D date datetime PDF
SupplierM M date datetime PDF
SupplierQ Q date datetime PDF
SupplierY Y date datetime PDF
ReportName为报表的名称,PeriodType为报表的类别,分别是日报,月报,季度报和年报,PromptName1和Prompttype1为参数的名字和类别,如果有需要,可以加更多的参数。Format为报表导出的格式。(为方便描述,下述代码中的参数都写死,实际操作中,会从数据库或者从注册表中读取。)
定义参数的代码为:
ParameterValue[] parameters = null;
parameters[1] = new ParameterValue();
parameters[1].Name = “date”;
parameters[1].Value =”01/01/2008”;
定义其他参数:
string devInfo = @"<DeviceInfo><Toolbar>False</Toolbar></DeviceInfo>";
string encoding;
string mimeType;
Warning[] warnings = null;
string[] streamIDs = null;
DataSourceCredentials[] credentials = null;
ParameterValue[] used = null;
第三步,生成报表并得到报表的二进制流
ReportingService rep = new ReportingService();
rep.Credentials = rep.Credentials = System.Net.CredentialCache.DefaultCredentials;
byte[] ss = null;
得到报表:
ss = rep.Render(“SupplierD” , “PDF”, null, devInfo, parameters, credentials, null, out encoding, out mimeType, out used, out warnings, out streamIDs);
使用的方法是RS提供的
Render ( Report As string , Format As string , HistoryID As string , DeviceInfo As string , Parameters As ArrayOfParameterValue , Credentials As ArrayOfDataSourceCredentials , ShowHideToggle As string ) As base64Binary
第四步:将生成的报表保存到服务器
FileStream repFile = new FileStream(@“D:\Report\ SupplierD”, FileMode.Create);
repFile.Write(ss, 0, ss.Length);
repFile.Close();
第五步:自动打印生成的报表
System.Diagnostics.ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.Arguments = "/p /h " + @“D:\Report\ SupplierD”;
startInfo.FileName = @"C:\Program Files\Adobe\Reader 8.0\Reader\AcroRd32.exe"; ; //Replace this with the path of the Acrobat Reader executable file, i.e. AcroRd32.exe
startInfo.UseShellExecute = true;
System.Diagnostics.Process process = Process.Start(startInfo);
process.WaitForExit(10000);
if (process.HasExited == false)
{
process.Kill();
}
这里的方法其实是打印已经生成的PDF文件,所以要求该机器必须装有Acrobat Reader。不选用直接打印二进制数据流,是因为这种打印方法无法设置横向打印(Landscape)或者是竖向打印(Portrait),而报表肯定是有横向有竖向的。不选用打印生成html文件的方式,是因为RS不支持导出HTML,只支持MHTML,而MHTML转成HTML太麻烦。
最后,有几点需要注意的是,RS导出的报表必须是已经发布到Report server上的,调用render方法时,第一个参数Report As string必须和reportserver上的路径一致,比如报表的发布路径是Report/SupplierD,那么这个参数的值为”Report/SupplierD”。还有一个要注意的是如果制作报表时,参数设置成下拉框式(如下图),那么传入的值必须是这些值其中之一或者之几(看是否是Multi-value)。
![]()
留言请访问如下链接:
Reporting Service Tips 101(#4) - 使用RS实现报表的自动生成以及在程序中调用RS
接上一篇(Reporting Service Tips 101 - 关于使用Sum函数会遇到的问题(1)),谈谈使用sum可能会遇到的另外一个问题。
Dateset的数据如下:
Supplier Revenue status
A 5.00 0
A 6.00 1
A 7.00 0
需求是只用sum算出Supplier A在status为0时候的Revenue总和。单看这个需求,我们其实很容易用在报表中添加分组,或者直接在数据的上一层group来解决,但是在做很多复杂报表的时候,如果能够在计算公式里面去解决一些问题,整个报表的开发过程会简单得多。
报表如下:
![]()
计算公式为:=FormatNumber(Sum(Fields!Revenue.Value and Fields!status.Value=0),2)
结果如下:
![]()
可以看到,正是我们想要的结果。但是这种方法,在遇到很复杂的报表的时候,有时候会有问题,所以我们还可以用另外一种方法。
报表:
![]()
计算公式为:=FormatNumber(Sum(iif(Fields!status.Value=0,Fields!Revenue.Value,0)),2)
结果:
![]()
和上一种方法的结果一样,但是这种方法的好处是,基本上无论多复杂的报表,都不会有问题。
留言请访问如下链接:
Reporting Service Tips 101(#3) - 关于使用Sum函数会遇到的问题(2)
用过Reporting service (后面都用RS代替)的人对sum这个函数都不会陌生,这个函数的使用率极高并且非常好用,下面我们就来谈谈使用这个函数可能会遇到的一个问题。
我们先假设报表使用的dataset传过来的数据如下
Supplier Revenue
A 0.00
B 0.00
报表的需求是要算出每个Supplier的Revenue所占的比率。我们在报表中新建一个table,table中新建一个group,group绑定的值为Fields!SupplierName.Value,group的名字为SupplierGroup,该Dataset的名字为Dssup。报表如下:
![]()
可以看到比率的计算公式为:
=FormatPercent(Sum(Fields!Revenue.Value,"SupplierGroup")/Sum(Fields!Revenue.Value,"Dssup"),2)
但事实上,由这个计算公式得到的值却是这样:
![]()
这个很好理解,是因为我们的计算公式的分母为0,所以出现了NaN这种值,这个时候,按照正常的逻辑,我们都会选择先判断一下分母,改后的计算公式是这样(为了便于查看,先去掉函数FormatPercent):
iif(Sum(Fields!Revenue.Value,"Dssup") = 0, 0.00%, Sum(Fields!Revenue.Value,"SupplierGroup")/Sum(Fields!Revenue.Value,"Dssup"))
这个是说如果分母为0,那么传回0.00%,反之通过公式计算。从这个公式来看,没有问题,但是不幸的是,结果依然是NaN。
那么怎么办呢,继续尝试下去,改计算公式为
iif(Sum(Fields!Revenue.Value,"SupplierGroup")/Sum(Fields!Revenue.Value,"Dssup")=’NaN’, 0.00%, Sum(Fields!Revenue.Value,"SupplierGroup")/Sum(Fields!Revenue.Value,"Dssup"))
结果证明,改成这样,还是不行。
这个时候,考虑到当Sum(Fields!Revenue.Value,"Dssup") = 0 时,Sum(Fields!Revenue.Value,"SupplierGroup")一定也为0,所以改计算公式为:
Sum(Fields!Revenue.Value,"SupplierGroup")/iif(Sum(Fields!Revenue.Value,"Dssup")=0,1,Sum(Fields!Revenue.Value,"Dssup"))
既如果分母为0,那么强制将分母变为1,最后结果为
![]()
这是我们想要的结果。最终计算公式是:
=FormatPercent(Sum(Fields!Revenue.Value,"SupplierGroup")/iif(Sum(Fields!Revenue.Value,"Dssup")=0,1,Sum(Fields!Revenue.Value,"Dssup")),2)
ReportingService有三种报表发布方式:
一、是在报表管理器上直接上传报表,创建数据源,这种方式很麻烦,只适用于少量的报表。
二、是在VS.net里的project里面直接发布,这种只适用于开发环境。
三、就是使用RSS脚本进行自动发布。下面我们就来初步了解一下RSS这种发布方式。
默认情况下,安装完Reporting Service,我们可以在Microsoft SQL Server\90\Samples\Reporting Services\Script Samples目录下找到一个名为PublishSampleReports.rss的文件,同时在联机文件中,我们也可以找到该文件。这个RSS文件就是自动发布的脚本,但是内容比较基础简单,下面我们在这个文件基础上进行一些扩展。
1. 这个是一个比较重要的问题,提供的RSS脚本,要求默认windows认证或者允许匿名访问,但是在实际的生产环境中,一般是用的域认证,且出于安全考虑,禁止匿名访问。所以这一块,我们要改变RSS的认证方式。
已有的代码是:
rs.Credentials = System.Net.CredentialCache.DefaultCredentials
改为:
rs.Credentials = new System.Net.NetworkCredential(User_Name,User_Password,User_domin)
然后在命令行里面加上这三个参数即可:
rs -i PublishSampleReports.rss -s http://ReportServerName/reportserver -u UserName -p UserPassword\Userdomin
在指定的服务器上进行发布时,有关权限问题这一块,我们还应当考虑是否拥有报表服务器的访问权限,以及是否对对要访问的报表服务器的根文件夹具有相应的权限。在实际操作中,权限问题是报得最多的error。
2.该脚本必须用Visual Studio VB.NET语言编写,因此也可以用VB.NET进行一些额外的操作,例如判断报表是否已经被发布。
【原文地址】ASP.NET Ajax Roadmap Published
【原文发表日期】04 July 08 07:07
Bertrand最近发布了我们的ASP.NET Ajax路线图。
我们的目标是描述一部分被提议的特性,我们考虑在未来版本的ASP.NET AJAX, Visual Web Developer和ASP.NET AJAX Control Toolkit中加入这一部分特性。
我们非常感谢你的反馈,因此这篇文章的目的是想让你对我们的前进方向提供宝贵意见,同时也让你了解一下我们团队现在的努力方向。
我们将乐于倾听你的意见!
IT界是一个特别适合“创新”的地方,尤其是各种各样的术语。各大厂商为了自己的利益,不断的推出一些新的术语,而媒体们也在不断的站队,跟着一些忽悠,搞得我们这些IT界的前线战士们一阵一阵得晕。刚刚有了B/S、C/S、SaaS、SOA、Mash Up以及S+S,现在又出来了云计算。
什么叫云计算?根据维基百科当中的定义(基于某种原因,可能无法访问维基百科):云计算(cloud computing,分布式计算技术的一种,其最基本的概念,是透过网络将庞大的计算处理程序自动分拆成无数个较小的子程序,再交由多部服务器所组成的庞大系统经搜寻、计算分析之后将处理结果回传给用户。透过这项技术,网络服务提供者可以在数秒之内,达成处理数以千万计甚至亿计的信息,达到和“超级计算机”同样强大效能的网络服务。
很深奥的概念,相信很多朋友可能和开心一样,有些云里雾里,真的掉到云里面去了。而且在下面的云计算示例一节当中,又给出了两个简单的云计算案例,即搜索引擎以及网络邮箱。俺就有一些搞不明白了,按照这种示例,所谓的云计算,与B/S以及C/S架构到底有什么不同呢?如果再看看各大媒体举的例子,把一些在线文档编辑器也称之为云计算,那么云计算与SaaS又有什么区别呢?这不就是经典的新瓶装旧酒吗?
其实,云计算的先驱真的不是Google(谷歌)或者微软,而是亚马逊(Amazon)。让我们来看一下所谓的B/S以及C/S架构,如果从分层上来看,其实都是Client to Server的层次(只不过B/S中把C换成了Browser而已)。而无论在Client端还是Server端,都适用于经典的软件销售,在Client端,我们有Office、Windows Vista、Firefxo,而在Server端,则有SQL Server、Oracle、Apache。这些软件都适用于software license的销售模式(软件收费或者支持服务收费)。
而亚马逊的EC2则更改了Server端的software license模式,其最主要的含义是将软件的功能以服务的方式提供出来,然后根据类似于SLA(Service Level Agreement)的方式为其客户提供相应的服务。比如EC2当中的Simple DB,就是一个网络存储服务,类似于SQL Server/Oracle等等,你在开发的时候,不需要安装经典的数据库应用程序在服务器上,根本不用在意我的数据到底存在“哪块云里面”,而且开发的时候还可以使用原来的SQL语句进行CRUD(不知道CRUD是什么意思?赶快做一下功课去吧),任何时间,任何地点,任何设备都可以进行访问。听上去很美吧?
所以云计算其实就是C/S的一个扩展版本,简单可以描述为C to S to S (C/S/S),实质就是一个更新版本的SaaS,服务器端的Software As A Service。大小S之间进行计算以及数据的传输,最终把结果输给C,让C来展示就可以了。而云计算指的其实就是S to S这一端,所以与最终用户根本无关,甚至最终用户根本感觉不到这种改动,所改动的其实就是开发商如何采购其服务而已(是购买软件还是租用服务)。所以俺开心个人认为,传统的搜索引擎以及网络邮箱,或者在线文档编辑器(Google Docs)还称不上什么云计算(当然,你硬说里面也有S to S之类的云端交流,俺也不没有什么理由来说服你)。
ASP(Application Service Provider)其实也是云计算的一个先驱,但它是把应用构建在云端,而不是把服务构建在云端,所以造成了其上的二次开发商非常稀少,而没有建立起完整的生态链系统,最终进入到失败。而云计算由于只是把服务器端的Software更改为Service方式应用(云上的API),所以可以召募很多的二次开发商,从而快速得构建起完整的生态链。相当于IT界的一次洗牌过程,抓住了云也就抓住了未来,对于传统软件厂商来说,其危害要比Open source有过之而无不及。整个生态链可以基本上划分为云间服务提供商(相当于原来的服务器端的软件厂商:微软、甲骨文、IBM等)、应用开发商(基于服务构建应用的厂商,SI或者ISV等)以及最终用户等。
但云计算也不会一帆风顺,肯定会有乌云时期,有兴趣的话,可以去了解一下Amazon的EC2的业绩。我们可以先抛开欧美日印市场,从国内的IT环境来看,无论是从政策、技术或者信用等来说,目前还极度不成熟。非死不可(Facebook)本周在国内的突然病亡会在很长一段时期让大家对于云计算充满怀疑(谁又能够预料哪一天App Engine突然发动不起来了?),现有的云计算的开发模式对于重视技术迁移成本的开发商也处于观望状态。
所以云计算虽然看上去很美,但实际上要走得路还是很长。
在接下来的话题当中,开心还想聊聊云端的梦(从最终用户角度会感觉到的优势)、吞云吐雾的幻术(从开发者角度选择最好的云计算平台)等话题,欢迎大家交流。
[原文地址]:June 27th, 2008
[原文发表时间]:Friday, June 27, 2008 2:25 PM
今天是很特别的一天——至少对我们这些在微软的人来说是这样。
全世界都知道了这个消息,今天是Bill Gates作为微软全职雇员的最后一天。
在这里请允许我分享一些我的观点和想法。
作为微软的一部分,投身于伟大的产品和技术,提供给世界各地的人使用……我经历了非常美好的时光。与Bill Gates领导的微软高层共事,对我来说获益良多。过去的这些年来,我有很多机会与Bill接触,并从中学习。Bill是我非常欣赏和尊敬的人。
我从Bill那里学到的事情中,最重要的方面是以下几点:
- 全局思考,有宏伟的梦想
- 从长期发展的角度进行思考和优化
- 软件的力量是很强大的,在我们的工作下,软件已经前进了很多,但还有很大的成长空间
Bill通过软件、计算技术和微软,在世界各地创造了空前的影响力。现在他决定将更多时间和精力转移到基金会方面的工作。我想要感谢Bill所做的一切,并祝他的未来一切顺利。
这里是一个Channel 9视频,您将看到微软人分享与Bill的故事。
Namaste !
本文概述
StreamWriter 在产生UTF-8编码的内容时候,会在产生的这个UTF-8内容中增加BOM的信息,而这个BOM的信息,会干扰我们在一些情况的使用。
本文描述的情况,就是这种干扰让我们无法正常工作的一种情况。
何为BOM?
BOM(Byte Order Mark),BOM签名。
BOM的内容就可以表示unicode文件是何种编码。BOM签名的意思就是告诉编辑器当前文件采用何种编码,方便编辑器识别。
对于UTF-8 , BOM 信息为 EF BB BF。 我们如果在Google搜索 UTF-8 BOM 就会搜索到很多文章, BOM 在不少情况下,都会给我们添乱子。
下面是我碰到这个问题的描述
我碰到这个问题的场景:在书写一段模拟HTTP Post 请求的时候, 代码如下,但是却无法模拟Post请求:
private void do2() { string url = "http://localhost:39749/Default.aspx";
string indata = "__VIEWSTATE=%2FwEPDwUKMTQ2OTkzNDMyMWRkyGd"; indata += "iqWjBKr5rIKmHzSdD9AaojKw%3D&Button1=Button&__EVENTVALIDATION=%"; indata += "2FwEWAgLohfrVDQKM54rGBu49QLoa7JmG9cEfUpTccMrUmJfD";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "Post";
Stream myRequestStream = req.GetRequestStream();
StreamWriter myStreamWriter = new StreamWriter(myRequestStream, Encoding.UTF8);
myStreamWriter.Write(indata);
myStreamWriter.Close();
myRequestStream.Close();
myStreamWriter.Dispose();
myRequestStream.Dispose();
HttpWebResponse res = (HttpWebResponse)req.GetResponse();
StreamReader reader = new StreamReader(res.GetResponseStream(), Encoding.UTF8);
string info = reader.ReadToEnd();
reader.Close();
res.Close();
reader.Dispose();
MessageBox.Show(info);
}
而文中中间的代码修改成下面代码则可以成功模拟。
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(indata);
req.ContentLength = bytes.Length;
Stream myRequestStream = req.GetRequestStream();
myRequestStream.Write(bytes, 0, bytes.Length);
myRequestStream.Close();
为何会这样呢?分析原因,竟然是 UTF-8 BOM 在作怪。
StreamWriter 在产生UTF-8编码的内容时候,会在产生的这个UTF-8内容中增加BOM的信息, 这样他发送的Post信息就比正常多了三个字节 EF BB BF。 就是因为这三个字节导致服务器端无法处理正常的Post请求。
解决方法:
1、自己重写UTF-8类,参看 http://www.19870202.com/?tid=381 。在调用的时候用这个自己写的类。
重写代码:
public class UTF8EncodingNoPreamble : System.Text.UTF8Encoding
{
public override byte[] GetPreamble()
{
return new byte[0];
}
}
2、不要用 StreamWriter ,参看我上面的替代方案。
参考资料:
System.IO.StreamWriter写UTF-8文件不写BOM
http://www.19870202.com/?tid=381
UTF-8, UTF-16, UTF-32 & BOM
http://unicode.org/faq/utf_bom.html#BOM
utf-8 保存文件的 bom 问题
http://www.uuzone.com/blog/tom/101761.htm
使用方法参考这里:SharePoint文件磁盘存储组件使用指南。
WSP安装包下载:WSSv3.DiskFileStorage.wsp (源码 (Update 2008-6-24:为了方便大家使用源码,将源码改成了使用VS2008 + VSeWSS 1.2) )
警告:仅仅是测试版,请仅用于测试(或者你直接把源码改到认为已经足够稳定也行)。有问题请到我的备份blog(http://kaneboy.spaces.live.com)此克隆贴下留言。
先从SQL注入攻击说起吧。
前一段时间的SQL注入攻击可以说让国内以及国外大量网站沦陷,几个攻击变种中幸好是update而不是delete,否则众多网站损失更大,不过从犯罪的角度来说,并不是这些攻击者心慈手软,而是update才能置入网页木马,也才能在置入成功后获得预期的利润。
在很多所谓的开发高手来看,SQL注入只是菜鸟才会犯的低级错误,其实不然。一个中大型的网站,在他不断发展的过程中,网站门户的程序都是Patch模式的逐步叠加,随着页面的增加以及版本的螺旋上升,SQL注入的危险百分比也会指数增长,尤其是国内各个网站开发的模式而言。当一个中大型网站的页面达到几万甚至几十万的时候,当这个网站的程序不断叠加积累,诸多历史页面已经处于失控的时候,如何避免SQL Inject攻击将会是一件令人非常头疼的事情,因为你此时是不可能完全重写整个网站或者完全对所有页面做代码安全审核的。
在这众多的历史页面代码中,一个微小的疏漏就导致你的DB完全向攻击者敞开,甚至威胁到服务器磁盘数据。
我以SQL Inject为例就是为了说明其实Web威胁攻击并不是说需要多么高深的技术才可以进行实施,这些攻击往往是你在认为很简单就可以抵御的时候来进行实施的。另外一个极端就是,所谓的社会工程学攻击,各位可以Google一下就会了解。可以说 ,目前的各类攻击已经不再像很早以前那样为了显示自身技术而进行的有意或无意的攻击破坏了,现在大量的Web攻击都是带有利益驱使性的,也更具危害性。
这些Web攻击都是非常危险的,因为不论你的硬件防火墙或者入侵检测系统如何强大,是无法判断这类Web攻击的,因为它们都是合法的HTTP请求。所以根据统计,目前的Web攻击除了操作系统以及各类服务器端应用软件的漏洞外,绝大部分(70%以上)都是此类“合法的”Web攻击。
因此,抵御此类攻击一是需要检测你的应用程序代码,二是可以采用服务器端的针对访问请求以及内容的检测过滤。
针对第一类,目前业界有非常多的安全检测工具,比如HP WebInspect,NStalker-WAS(NStalker-Web Application Security Scanner),IBM Rational AppScan(Watchfire AppScan),Acunetix Web Vulnerability Scanner等等,当然这里我列举的都是商业软件,而没有包含相应的开源软件,在这方面而言,商业软件用来做安全威胁评估的优势更明显,也更合适。
这类模拟攻击检测软件有庞大的规则库以及模拟场景库,可以代替繁杂易错的人工检测。
针对第二类,则可以通过服务器端的过滤和监测机制来最大程度上保证IIS Web服务器的安全,比如微软的IIS Lock。在IIS 7推出后,做此类过滤更加简单和便捷了。国内外也有针对此类的软件产品,比如Port80 ServerDefender。这类产品可以在服务器端对于HTTP Request / POST / Cookie等做过滤和检测,抵御此类Web攻击。
(此图片转自于IBM网站,特注明)
排名前两位的是XSS攻击以及SQL Inject攻击。对于XSS攻击,很多开发者想必会嗤之以鼻的,因为目前而言XSS攻击都很少能破坏掉服务器端的数据,但是XSS最大危害在于钓鱼式攻击,这对于一个成功的网站而言,对其信誉的打击将是致命的,因为展现在用户面前的是合法的网站URL地址,只是XSS攻击部分被编码了。一旦用户遭受此类攻击,对于你网站的信任将会大大降低,现在有什么比得罪你的忠实用户的危害性更大呢?
上面我们提到了很多安全检测工具,其中提到的那四种工具我都有过一定使用(Trial或者Test),其中的AppScan是我印象最为深刻的,也是效果较好的一个。Rational家族随着IBM的不断收购,已经越来越庞大,通过收购Watchfire从而获得了这款企业级安全检测产品,并被Rational产品系列所整合,使之符合Rational的完整涵盖软件生命周期的目的。
Rational AppScan开发版本会有针对于Visual Studio 的AddIn,来在程序开发过程中就能进行代码安全审计和检测;同时也有QA版本;当然我们使用更多的是产品发布后定期的安全审计以及检测了。各版本的比较可以参见:http://www-142.ibm.com/software/dre/hmc/compare.wss?HMC02=C126096V43460Q17
Rational AppScan 7.7全功能测试版本在IBM网站可以免费下载到(http://www14.software.ibm.com/webapp/download/search.jsp?pn=Rational+AppScan),目前CSDN好像也在进行AppScan的市场活动,有兴趣可以去CSDN找一下即可。
下一个post会详细讲述一下如何针对一个真实网站进行安全审计。
---
可能的大概目录
Web攻击和防御(一) - 安全检测工具(1)介绍
Web攻击和防御(二) - 安全检测工具(2)AppScan详解
Web攻击和防御(三) - 安全检测工具(3)AppScan数据分析
Web攻击和防御(四) - IIS安全防护,IIS Filter介绍
Web攻击和防御(五) - IIS安全防护,IIS Extend介绍
Web攻击和防御(六) - IIS安全防护,IIS 5.x 、6、7区别对待
Web攻击和防御(七) - Web Server Guard介绍
Web攻击和防御(八) - Web Server Guard安全防护使用详解
Web攻击和防御(九) - Web Server Guard性能调优使用详解
Web攻击和防御(十) - Web Server Guard服务器监测使用详解
Web攻击和防御(十一) - 完成不可能的事情:使用C#编写IIS Filter(IIS 5.x/6.0)
Web攻击和防御(十二) - IIS 7.0 Filter
Web攻击和防御(十三) - IIS 7.0 安全防护
Web攻击和防御(..... ) - ..........
[原文发表地址]: ¡Bienvenido!
[原文发表时间]: Tuesday, June 17, 2008 8:49 AM
看着世界各地的软件开发都在迅速增长,是如此令人陶醉和兴奋。去年,十分荣幸的有人(来自Microsoft内部以及外部社区)将我的网络日志翻译成中文和日文,以方便更广泛的读者群体阅读。有不少人请求将我的网络日志翻译成西班牙文。这件事我已经考虑了一段时间了,终于在开发工具部内部找到了几个志愿者帮我做翻译。
现在,我的网络日志有英文、 中文、 日文和西班牙文等不同版本,这让我能接触到更多的热爱编写软件的人。
Namaste !
好久没有些东西了,好像大家最近都很忙,写东西的人不多。最近事情真的很多,国家大事多,体育赛事多,。。。。
SQL Server 2008 RC0已经发布了,但是我还没有去download呢,因为再等新机器,T61P,装了x64的系统,装SQL当然也要x64的,所以要等等。SQL Server 2008很多人都还没有用过,Webcast上倒是已经有很多课程了,大家可以去学学,很多新的功能还是不错的。我最近一直在做关于FileStream的东西,好多人也会有这种疑惑,为什么要把Blob数据,通俗的讲就是文件为什么要存储到数据库里,存到文件系统不是也很好吗?So.......美国人说话总是说So,大家可以想一个问题,如果你的文件很多,比如有N TB数据怎么办?还放到文件系统里吗?当然可以,放到哪里有你决定,但是文件很多的时候管理成本就会增加,而且存储成本也将不断的增加,客户需要一种文件管理的系统。Windows的文件管理并不是十分的好,如果你的一个文件夹中有数百万文件,估计这个文件夹也没办法展开了。多年前,我们还在用Windows XP&Windows Server 2003时,MS给了我们一个Idea-WinFS,新的文件管理平台,用数据库去管理文件系统,几百万条记录的检索在数据库中并不是很慢,至少不会像explorer一样死掉。但是遗憾的是在Vista中并没有发布这个东西。
在SQL Server 2008中的FileStream特性给我们提供了这样一个可能,就是WinFS,换个马甲我还认得,哈哈哈。我们可以把Blob数据存储到SQL Server中,当然数据空间并不是在传统的MDF中,还是在文件系统里,只不过我们可以通过SQL Server来进行管理,这样检索数据就会相对简单很多了。我们的这个客户Blob数据量估计在60T左右,按每个文件2MB,3千万个文件。千万级数据的查询应该不会太慢,因为我们没有什么关联的表。
但是MS的想法更大,一个大想法,RBS,Remote Blob Storage,也就是远程Blob存储系统,这个比WinFS的概念可就大多了,这个RBS就是希望通过利用更多小型的存储系统去替代那种昂贵的大型存储系统。当然这个RBS是一个Provider的模式,可以通过自己开发Provider来去实现各种存储的方式,可以存储到磁盘、磁带、数据库中,我们现在就是要做一个RBS Provider for SQL Database并且带有NLB的功能。这个大想法给用户带来的好处就是他们可以用统一的应用程序接口来去访问文件,而并不用关系文件存储的位置和存储系统,我们可以将数据存储在Near Line系统中当然这样的系统动不动就几个Million的$,也可以有一种选择放到数据库里面,当然通过RBS Client中我们就不用去知道后面这些东西怎么处理了,只要我们传一个StoreBlobId给RBS就可以了,我们通过自己实现的Provide算法去返回给客户端。RBS这个东西的目的很明显用SQL Server实现文件管理,当然这个是MS的目标,database这个词开始的时候就是做管理文件的,当然用RBS去连接其他的存储系统也是可以的,因为Provider的模式还是比较灵活的。这个东西还不知道是不是在SQL Server RC0中包含,但是RBS Client的代码是已经Completed。
以前我都很少研究Storage这个东西,毕竟好像和应用开发和数据库还有些距离,但是RBS这个就是介于Storage和App之间的一个桥梁,对于很多特殊的用户来说是非常有意义的,毕竟存储这个东西还是很贵的。
SharePoint文件磁盘存储组件可以将用户上传到SharePoint中的文件,存储到指定的磁盘目录中。基本原理可以参考我之前的blog。
1、安装Solution Package
使用stsadm.exe将Solution Package安装到SharePoint服务器上:
stsadm -o addsolution -filename DiskFileStorage.wsp
2、部署解决方案
3、在服务器场中激活“文件磁盘存储”功能
激活后,在服务器命令提示符中运行下列指令:
IISReset
net stop sptimerv3
net start sptimerv3
4、配置Web应用程序以启用此功能
在“管理中心 - 操作 - 数据配置”点击“用户文件磁盘存储”:
在下面的界面中配置每个Web应用程序是否启用磁盘存储功能,以及存储位置等:
搞定。
计划本周末提供组件Solution Pakcage下载。
[原文发表地址]:How vulnerable are software applications?
[原文发表时间]:Tuesday, June 17, 2008 5:56 PM by Somasegar
