木乃伊中的Bugs(2):Server.Transfer与Form提交的回传地址

可能有很多朋友发现了一些问题,比如使用http://blog.joycode.com/joy来访问开心的页面,或者使用http://blog.joycode.com/[Subfolder]方式访问其它堂主的首页(后面不加上default.aspx)的话,会遇到各种各样莫名其妙的问题。

1) 你当前未登录,使用登录链接进入到Windows Live ID登录校验后再次返回,会出现404错误;

2) 登录后,使用搜索按钮在该博主文章中搜索相应关键词时也会出现404错误;

先来讲讲目前的工作原理,大家知道,博客堂目前使用的是IIS7来运维的,而且我不太习惯使用通配符映射,总感觉那样性能消耗太严重,所以借用了Subtext中的方法,即使用错误页面映射,在IIS 7的错误页面当中指定自定义Url,即”~/SystemMessages/FileNotFound.aspx”来进行处理。这样当你访问http://blog.joycode.com/joy的时候,由于ASPNET_ISAPI无法对其进行处理,相应的各种HttpHandler/HttpModuler也无法对其进行操作,只能由IIS 7交给错误页面处理,亦即FileNotFound.aspx。

在FileNotFound.aspx当中我们来对原始请求的URl进行分析,如果发现用户其实访问的是一个堂主的首页的话,类似于http://blog.joycode.com/[Subfolder]这样的地址,那么就使用Server.Transfer,将相关请求转向到指定的首页地址,在这儿即”~/Skins/default.aspx”,当然,在转向前我们会将相应的BlogConfig信息也一并转向过去,这样大家看到的页面就是当初请求时所想要看到的页面。

但这时候会出现一个问题,即使用Server.Transfer(string path, bool preventForm)的时候,呈现的页面当中的Form的回传地址是真实的物理地址,而不是虚拟路径。在我们这儿是”~/skins/default.aspx”(感兴趣可以这几天在登录后,去各堂主的首页,将鼠标放在“搜索”按钮上,看看IE状态栏的地址指向,或者使用浏览源文件的方式看看该页面上Form的回传地址)。因为http://blog.joycode.com/skins/default.aspx根本不是某个博主的页面,而是后台通用的转向后的页面,所以我们在系统中将此页面进行了隐藏,所以最终当你搜索或者登录时会出现404错误。

这个问题很麻烦,不过我有号称活MSDN的宝玉同志,所以我并不着急。不过宝玉同志告诉我解决方案只能通过客户端的JS,来重新对于Form的URL属性进行改写。解决倒是可以解决,但总感觉不够优美,破坏了程序的整体性。所以开心用了一周的时间一直在思考此问题。

后来在阅读UrlRewriting的源代码时,发现它都是使用Context.RewritePath来重写路径的,于是我也尝试使用这种方案来代替Server.Transfer,但发现了一个问题,Context.RewritePath想要达到转向的目的,必须在HttpApplication.OnBeginRequest事件中才能生效。在一个ASP.NET Page页面中就没有办法解决了,事实上,在判断当前是不是一个堂主页面时,程序已经运转到Page.OnLoad事件了。

还能怎么办?与思归交流,他告诉我其实Context.RewritePath其实可以修改一些HTTP的内部参数,也就是说在调用Server.Transfer之前,调用Context.RewritePath还是有机会重写虚拟地址的。但我写了一个示例程序,发现其实根本没有修改。

既然Context.RewritePath还是有机会修改的,那么问题可能出现在Server.Transfer上面,能不能换一下其它方案,比如Server.Execute?试了一下,得到的结果不是我想要的。于是回过头来重新看Server.Transfer,发现它除了Server.Transfer(string path)的重载外,还有一个Server.Transfer(IHttpHandler)的重载。那么怎么从一个ASP.NET Page转换为IHttpHandler呢?查MSDN,终于我发现System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath就是做这个作用的,哈哈。赶紧试一下,竟然成功了!

测试代码如下:

   1:  private void RewriteUrl(string subfolder)
   2:  {

3: Context.RewritePath(string.Format("~/{0}/default.aspx", subfolder),

string.Empty,

string.Empty, false);

   4:             IHttpHandler handler = 
System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath("~/skins/Default.aspx", typeof(Page)) 
as IHttpHandler;
   5:             Server.Transfer(handler, true);
   6:  }                           

终于历经一周,我找到了解决方案,代码与原来的相比,就多了一行而已。

编程之美-微软技术面试心得

我喜欢面试人,不喜欢被人面试,我相信大部分技术出身的朋友都与我一样的想法.但活在这个业界,不可能不过五关斩六将的参加各种面试过程.面试结束,有的人很郁闷,有的人很兴奋.当然很多时候,这都是临场发挥的实力,但其实也折射出大家的综合素质.

相信很多人都知道微软的面试过程是比较特殊的,也有很多朋友在一些媒体上读到了类似于下水道井盖为什么是圆的等等所谓的微软面试题.对于微软的面试过程产生了敬畏.微软的面试过程也被蒙上了一层面纱,让人感觉非常神秘.当然我也相信有很多朋友经历过微软的面试后,会发现其实这些面试过程并不神秘.如果你”有幸”被我面过,会发现我从来不问“北京有几个公共汽车站”或者“黄河每秒钟的流量有多少”之类问题.其实原因就是开心现在工作的部门并不是研发部门,除了要求技术能力外,还需要一些市场运作能力等.所以面试过程会更加开放一些.

与邹欣认识比较久了,在微软刚刚开始"潜力发展计划"的时候,我们在济南做试点,就曾经邀请过邹欣同志来济南进行演讲.那时候他还在总部工作.后来去美国的时候,又与邹欣聊过后来,一直建议他回国发展.最终现在邹欣在微软亚洲研究院工作.邹欣同志是一个面试老手,不知道有没有博客堂的读者也被其面过,可以写写心得了.

从邹欣拿来他回国后主编的第二本书《编程之美-微软技术面试心得》,我就开始不停的流汗,邹欣也太会"折磨"人了吧,这些题目简直堪比满清十大酷刑呀,比如第一道面试题“CPU占用率曲线听你指挥”,让面试者写一段程序,控制任务管理器当中的CPU占用率的曲线一直显示为一条直线或者正弦曲线。后来通过各种搜索引擎进行搜索,发现还真有不少朋友做出来解答,还从网上把一些朋友的解答拿到本机进行测试,特别佩服某些朋友的思考能力以及创新思路。我相信,很多朋友假如第一次有机会来微软面试,遇到的第一个问题是这样刁钻的问题,不止会流汗,可能有些人会恨不得把鼠标抡起来,砸向面试官。

CPU曲线还是那个曲线,任务管理器还是那个管理器,但出这题的朋友以及可以答出这题的朋友都需要很多的思考,往往一些细节就可以考验出这些朋友的真功夫。

我也看到过其它公司的一些面试题,比如探讨一下Java的事件机制以及C#的事件机制有什么区别?重载与重写有什么区别?使用ASP.NET 2.0中的Master以及Theme机制写一个简单的个性化网页。通过这些面试题,我们可以看到每家公司所招聘人才看中的重点,大部分IT公司招聘的就是代码工人,只要会熟练使用工具,对语法熟悉就可以了。希望招聘到的员工经过简单的培训立即可以上岗。而微软的面试题折射出来的则是微软对于基础研究的重视。

我也在日常的客户接触当中,听过很多朋友抱怨C#/.NET太简单,不像Java那样高深,其实无论是Java还是.NET,或者其它产品性的技术,都是同等的工具而已,工具会有顺手不顺手的差异,在本质上没有什么差别,关键还要看自己的基本功。由此想到了前几天邹欣所写的《Arrays.sort() and 吾欲仁则斯仁至矣》。的确,现在中国的高校教育过于急功近利了,高校毕竟不是技校或者中专,培养出来一批工具使用娴熟的技术工人,高校培养的应该是真正有创造性思维的人才。

再由此想到了Google的面试,不知道是否是由谣传谣,说Google招聘某全球VP,最终由于此候选者无法拿出自己在大学期间的成绩单而被拒。也听说过Google在国内非常看重学历(以讹传讹?),所以出来了模仿Hao123的“网站导航”或者模仿搜狗拼音的“Google拼音”。

其实面试只是一个过程,面试并不能保证所有通过面试的人都是万中挑一的高手,没有通过面试过程的朋友也不必自怨自尤,毕竟面试过程与临场发挥、专业对口甚至面试官的心情都有关系。所以,放平心态就是了。

再次向大家推荐阅读这本《编程之美-微软技术面试心得》这本书。

如何使用博客堂

博客堂使用Windows Live ID之后,可能使很多朋友有些无所适从,不知道如何在博客堂进行注册,然后发表评论等.也有人担心在博客堂使用Windows Live ID登录或者注册会泄露自己的个人隐私,所以迟迟不敢进行下一步的点击,只能做潜水人员.

首先,开心在这儿进行一下声明,Windows Live ID的登录注册过程并没有大家想像的那么复杂.而且不会泄露个人隐私.更加详细的情况大家可以阅读:http://dev.live.com/liveID/default.aspx中的相关内容.简单来说,Windows Live ID是微软推出的一个完全不同于Passport的免费服务,任何网站都可以使用,可以使用ASP.NET/PHP/JSP/CGI或者其它任何网络编程语言进行调用.

其基本的注册过程如下:

1. 用户在第三方网站,如博客堂上,点击如下的登录/注册按钮.

image

2. 浏览器将会自动转向到http://login.live.com网站,让你选择你的一个Windows Live ID作为登录凭证.

image

3. 在您选择完登录凭证后,Windows Live ID将会自动将相关信息回复至http://blog.joycode.com/wllhandler.ashx,所谓的相关信息,不包括任何您在注册Windows Live ID时所使用的信息,比如您的邮件地址,头像,密码,生日等.只有一个类似于GUID性质的十六进制字符串作为您在本站的用户身份,wllhandler.ashx在拿到此信息后,会比对用户数据库,如果发现该字符串已经在博客堂注册过相关信息,那么将会直接将该用户设置为登录,如果发现该用户从来未在博客堂进行过登录,将转向用户注册页面:

image

4. 如果您是博客堂改版之前的博主,那么请点击”博客堂原用户绑定”,该面板会自动展开,让您输入原来的用户名以及密码,完成用户绑定工作,如果您原来在博客堂没有过老帐号,请直接在新用户注册当中输入您选择的用户名以及邮件地址(用户名必须为2-11位的中英文混合体),然后点击新建用户,系统会自动帮助您完成登录.以后您只需要使用该Windows Live ID就可以完成相关登录,再也不需要记录用户名以及密码了.在登录完成后,您可以点击您的个人信息面板中的”更新信息”按钮,进行相关设置:

image

5. 在”更新信息”页面当中,您可以输入自己的地区,生日等一些基本信息,还可以上传自己的头像,以便让更多的用户了解您.在主页模板当中,您可以选择自己喜欢的主页模板,在下次访问博客堂时将会使用相关的主页模板进行访问.上传头像时,请您在上传完照片后等照片都装载完成后,照片上出现十字型鼠标时,使用鼠标选择一块区域再点击”完成”按钮.否则该头像并不成功.

6. 博客堂首页中文章区显示的是由最终用户也就是您通过投票而产生的最佳文章,也就是使用的Digg模式,投票按钮需要在您登录后,进入到文章的查看区进行投票产生,如下图.在点击”推荐”时,会提示您每次投票都将消费您一分的博客堂积分(此举主要是为了防止有人恶意刷票,未来可能会拿掉).如果推荐成功,该文字会替换为”成功”二字,如果失败,则会显示为”失败”(失败的原因可能是系统问题,如果遇到,请与开心联系.另外,如果您的积分不够,会显示”积分不够”的信息,此时需要您通过发表留言等方式进行积分换取工作.

image

7. 通过首页上的”分页阅读最新文章”您可以以分页的方式按照时间顺序浏览博客堂最新发表的文章,通过RSS订阅方式获得的文章列表也是按照时间顺序发布的.

 

如果有任何问题,或者建议,欢迎大家提出.非常感谢.

人物点评(1): 马云的野心

可能有很多朋友注意到了,博客堂现在首页上挂了阿里妈妈的广告.在未来此种广告会挂在博客堂的所有页面当中,每个博主可以有权决定自己页面上方以及侧边栏的广告投放(包括是否投放以及投放代码等),而页面下方的广告则由站方控制,统一进行投放.

看过很多关于马云的文章,大部分是关于其生平的介绍,知道他当初也是师范生(开心本身是首都师范大学的物理教育系的学生),第一次接触互联网就开始制作中国黄页网站,而后做出来了B2B的阿里巴巴的网站,再后来出现了C2C的淘宝网.这两个网站的定位是不同的.但由于都牵扯到网上支付,所以很快,阿里巴巴推出了支付宝(Alipay)网站.用以完善阿里巴巴以及淘宝网的线上支付功能,同时又多了一个新的赢利点.

但收购雅虎中国,对于开心来说有些大跌眼镜,因为阿里巴巴的业务线基本上都是电子商务,而雅虎中国作为一个大众门户,其对于阿里集团的贡献到底在哪儿?难道是线上广告营收?但这种经营过于分散,对于一个集团来说并不是好事情.

我们可以看到,国内几大门户网站,都有其核心业务,百度以搜索起家,其所有的业务也都围绕着”搜索”,即使是贴吧或者百度Hi,其实都是为了聚焦搜索内容而进行的(这有些模仿谷歌的Groups以及GTalk).腾讯的业务就更加集中化了,一切都是围绕着QQ而建设,可以看到,腾讯推出的新业务基本上都会在其QQ界面上有所反应.如果某个新业务没有在其QQ界面上有一席之地,其发展前景也不容乐观.比如曾经的腾讯Campus网站(http://uu.qq.com),在曾经欢极一时后,现在基本上无法访问了.其实这个网站原本可以做出与校内网(http://www.xiaonei.com)一样的规模出来.

阿里集团的发展方向有些类似于携程网,都是把线下业务搬到线上来运营的,其与互联网并不是那种深耦合性的.如果有了新媒体的出现,可以很容易的脱离互联网这种媒体形式而进行相关的经营.所以收购雅虎中国之后,我感觉马云也有些摸不清方向了,所以在收购后没有多久,雅虎中国不停在换将,其与雅虎全球的关系也有些纠缠不清.

而后,阿里妈妈的出现更让开心大跌眼镜,一个电子商务网站怎么开始做广告主?马云到底是怎么想的?再仔细一想,也不难明白.中国有句古话,叫”酒香也怕巷子深”,那些混在阿里巴巴以及淘宝上的网商们也有打广告的必要,而互联网广告是目前成本最低的广告形式.所以马云抓住了这一需求,适时推出了阿里妈妈这一广告集中批发市场.真是充分挖掘了网商的需求.

image而后,广告主越来越多,那么到哪儿找出来相关的媒体主呢?也就是打广告的平台?我们知道,广告是一种眼球经济,值得关注的广告才会有适当的投入产出比.广告主肯定喜欢流量高的网站.我相信马云也不愿意把相关的广告经营权全部送给其它门户,而且大家环眼望去,没有几家门户网站支持第三方广告投放,无论是Windows Live Spaces还是新浪博客或者其它第三方BSP,不会允许博主们自己投放相应的广告,这就使得广告主们即使有钱也找不到地方花.

咋办?自力更生.马云现在找到了雅虎中国的定位了.本身雅虎中国就是流量相对较高的网站(雅虎全球可是全球流量最高的网站,所以微软也瞄向了它,虽然雅虎进入中国以后经营一直就不太好),只要在上面花点精力,就可以积少成多.

现在大家访问一下雅虎中国网站,看看其导航栏中的顺序,最能吸引你眼球的是哪一块呢?站长天下!这是雅虎中国自己的业务,不相信的话,可以对比一下雅虎全球的网站.简单来说,站长天下允许就是所有的雅虎用户都可以在其上建站,相当于个人自助建站的一套工具.最主要的特点是你在上面建立了个人站点后,可以通过阿里妈妈来投放广告并且赚取个人收益.

到现在来看,马云已经通过一系列的举措把整个生态圈给打通了,网商-广告主-媒体主,这已经形成了闭合的生态圈,接下来要做什么呢?

既然目前是建立在互联网平台上,那么对于互联网平台的研发也不容忽视,所以马云又构建了阿里软件(alisoft),从事互联网平台的开发工作,以软件加服务为立足点,为中小型企业提供服务.如果大家关心一下业界新闻的话,可以知道马云除了每年在杭州举办西湖论剑的高层聚会以及每年一度的网商大会外,从去年开始,又开始做每年一度的中国网络工程师侠客行大会.

如果让我个人画一个阿里集团的组织架构图的话,我想下面就是我的基本构思了.

不知道阿里集团是否会进入到物流系统当中再干一番事业呢?就现在看来,这里面还差一环和物流相关的子系统.

以上内容,只是开心个人观察而总结出来的观点,仅代表个人观点,如果有所不当,请告之,非常感谢.

木乃伊中的Bugs(1): MembershipUser.IsOnline与Profile的关系

开心相信,博客堂的很多朋友都看过电影木乃伊,记得有一个场景就是当某个木乃伊复活前,从地下爬出来很多很多黑黑的小虫子,而且数量一直在急剧增加,这个是我看到过的比较恐怖的场景.去年在美国参加MIX07的时候,曾经跑到好莱坞的环球影城中体验了一把这种仿真场景,坐着过山车来到一个墓地,突然地下面跑出来很多虫子,围着自己的脚打转(其实应该就是风机吹的小风),虽然知道不是真的,但那种感觉还是让自己感觉很颤抖.

在开发博客堂新版本的时候,我也经常有这种感觉,时不时的就发现自己的应用程序当中出现了一些小Bug,当把这些小Bug给杀死的时候,你会发现会有更多的Bug出现,周而复始,有时候会让你想把服务器给砸掉,把内存拔下来,把硬盘给踩碎的感觉.呵呵,估计每个程序员都有过类似的想法吧?

开心相信,每个Bug之间都有关联,所以我们需要擒贼先擒王,找到主要的Bug,然后再进行跟踪,虽然现在博客堂的服务还不是非常稳定,但开心准备与大家一起分享这种捉Bug的乐趣,下面是第一篇.

先讲第一个小Bugs.在博客堂当前使用的版本当中,重载了MembershipProvider, RoleProvider以及ProfileProvider,比如在MemberShipProvider中增加了一个静态方法,MembershipUser GetUserByLiveID(string GUID),入参是由Windows Live ID传递过来的一个唯一标识(类似于GUID),而返回值则是MemberShipUser类型的变量.当在系统中发现当前Live ID登录者已经与用户进行过绑定时,会返回此MemberShipUser,如果未绑定,则返回null.这个方法目前运行良好,既没有破坏MembershipProvider的整体性,还起到功能扩充的作用.

另外,可能大家注意到了在首页上还显示了当前用户是否在线的状态,其原理并不是使用Messenger的API调用的,因为实际上Windows Live ID登录过程当中,系统只能得到一个唯一标识符号,并不能拿到大家的Live ID以及其它任何信息,所以在线状态使用的是MembershipUser.IsOnline来进行判断的.相信大家对于这个判断过程应该有所了解了:通过MembershipUser.LastActivityDate中存储的时间,是否大于系统当前时间减去在web.config中配置的UserIsOnlineTimeWindow(Membership配置节)的时间间隔来进行比较来判定的.MembershipUser.LastActivityDate标识用户在系统当中最后一次活动的时间,而UserIsOnlineTimeWindows给出一个以分钟为单位的时间间隔(目前博客堂设置的是20分钟).

这样就有了一个问题,即什么时候系统会更新这个LastActivityDate的时间值?通过Membership.GetUser(true)来获取当前用户信息的时候,会自动更新此值.或者你自己手工更新MembershipUser.LastActivityDate,并且再调用Membership.UpdateUser方法的时候也会更新此值.但可能没有人会想到,你使用Profile.GetPropertyValue(string propertyname)的时候也会更新此值吧?

比如,现在在博客堂,你点击某个人的头像的时候,会查看此人的信息,比如生日,积分以及地区等,这些信息其实是存储在Profile当中的,系统会自动通过Profile.GetPropertyValue(string propertyname)来获得相应的值,但如果你查看一下此时所调用的存储过程,会发现它竟然会自动更新对应用户的LastActivityDate的值.从而导致了一个怪现象,就是昨天的时候,你只要点击某个人的头像,某个人就会联机了.

解决方案也很简单,在后台对应的存储过程当中,删掉Update语句即可.

如果在您的应用当中,也使用了MembershipUser.IsOnline来标识用户状态,并且使用Profile来存储用户的一些基本信息的时候,切记要注意此部分.

参考文章: http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=103554

博客堂机房迁移

接到万网通知,博客堂所在服务器本周六(2008-3-8)为庆祝国际三八妇女节,将会迁移到多线机房.新机房将为所有独享主机提供BGP多线网络接入,包含网通、电信、铁通、移动、联通、教育网和科研网等网络资源,通过与六大电信运营商建立BGP连接为用户提供国内最好的互联互通网络平台并针对DDOS网络攻击提供了专门的解决方案。迁移后您的服务器将享受到更高质量的机房环境、更充裕的网络资源和条件、更高级的安全防护措施、更快速的问题响应以及更周全的服务内容!

所以从本周六上午十点,至晚上十点左右,博客堂将无法访问,在迁移结束后,将重新提供服务,同时,在迁移期间,博客堂本身也将完成相应改版:

1) 修改用户注册流程: 新用户注册时仅需要输入用户名以及邮件地址即可,不需要再输入其它信息;

2) 增加Digg模式: 首页中的随笔信息通过注册用户的”推荐”产生,排名根据推荐数量以及时间进行倒序排列,所有博主的随笔均有权在首页显示,但要根据访问者的投票来产生精华.

3) 增加最近访客功能:每个博主的空间均会增加相应的最近十位访客信息列表,让您知道谁在关注您的博客.

4) 各页面的随笔列表将改为摘要模式: 根据网友反馈,所有页面的随笔列表(包括首页,分类,存档等)均改为摘要模式,按照用户兴趣,进行点击阅读全文;

5) 首页RSS将提供摘要模式: 首页的RSS也将以摘要模式提供,各博主的RSS将根据个人意愿,提供摘要或者全文模式,各博主的RSS中的图片将换为博主个人的头像显示

6) 用户个人页面: 除了”更新信息”中增加了修改”心情”功能以外,还将提供用户个人页面,未来此页面中的形式可能会模仿Facebook,而且提供二次开发功能,以后只要点击某人的头像,就可以进入到该用户的个人页面;

7) 初步完成博主邀请权功能: 博主在后台管理页面可以查看到自己有几个邀请权,并且通过该页面将邀请权发放出去,注册用户在收到此邀请权后,可以自助在本站建立博客.

 

还是有请各位提交您所遇到的Bug,以便我们为您提供更好的服务:)