场景如下:
安装sqlserver2005中文版,然后升级vs2005以支持WebApplicationProject项目模版(就是从微软的网站上下载的那两个安装包,以支持使用vs2005开发WebApplicationProject)。问题就出来了:打开vs2005,发现大部分菜单都已经自动变成中文的,这个还好,当你准备新建一个project时,发现除了刚安装的WebApplicationProject项目模版之外,其他的项目模版都消失了!!!
解决的方式是:
1。找到 F:\Program Files\Microsoft Visual Studio 8\Common7\IDE\ProjectTemplates目录(如果你的vs2005安装在其他盘,前面的F就换成你安装时的盘符),将下面涉及到的所有1033目录下的 *.zip文件全部拷贝到与1033目录平级的地方,即:假如原来你的csharp windows项目模版文件在F:\Program Files\Microsoft Visual Studio 8\Common7\IDE\ProjectTemplates\CSharp\Windows\1033目录下,现在就转移到F:\Program Files\Microsoft Visual Studio 8\Common7\IDE\ProjectTemplates\CSharp\Windows目录下。其他目录以此类推。
2。在 开始-〉运行里执行 devenv /setup 命令,等待大约2-3分钟后,该程序运行完毕,再打开vs2005,既可看到“丢失”的模版有找回来了。
如果你的sqlserver2005是英文版则可能不会有此问题。
这个问题害得我跟踪摸索了3个小时,微软的网站上也没有任何这方面的兼容性说明,真tmd 崩溃!!!
上次,我遇到的 MagicAjax的中文问题, 当初为了演示,只是临时的使用了数字来绕过中文提交的问题,但不是最终的解决方法。今天终于忍不住这个乱码了,就打算解决它。先是到网上搜索一下,但都是说的另外一个问题。大部分人都是说把 magicajax post数据时的那个“loading...”修改成中文,出现乱码,这个好解决,这个汉字在 AjaxCallObject.js 文件里,直接把AjaxCallObject.js文件保存成utf-8就解决了。
我的问题是:页面上假如有个文本框,输入的是汉字,那么使用magicajax去提交数据到后台,在后台获取到的是乱码。打开magicajax的源码,找到 AjaxCallObject.js文件(之所以还是直接找这个文件,是因为ajax提交数据首先是通过js调用xmlhttp对象,将数据post到后台的,那么,就看看magicajax是不是把这个提交的数据进行了处理),找到使用xmlhttp提交的这段:
AjaxCallObject.prototype.DoAjaxCall =
function(eventTarget, eventArgument, ajaxCallType, ajaxScopeID, additionalData) {...... this.XmlHttp.open("POST", thePage, true); this.XmlHttp.onreadystatechange = function(){ oThis.ReadyStateChange(); }; this.XmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); this.XmlHttp.send(theData); }
可以看出在这里提交了theData数据,我用alert(theData)的方法将数据在提交前显示出来,发现提交的数据都直接显示是中文,然后再跟踪程序到后台,发现就已经是乱码了,这说明这个 AjaxCallObject.js 本身并没有对这个post的数据进行编码处理。
然后,就好办了,使用jscript里的 escape()函数将待post的数据在提交前编码一下,就不会出现中文了。代码如下:
if ( __bPageIsStored && eName == '__VIEWSTATE' ) continue; var type = curElem.type; var val = curElem.value; //这里对待提交的中文进行编码 //wangzhen 2006-07-06 val = escape(val); if ( type == "submit" || type == "button" ) continue; val = this.EncodePostData(val); if ( type == "select-multiple" || type == "select-one" ) { var selectLength = curElem.options.length; var optNameStr = this.EncodePostData(eName); for (var j=0; j < selectLength; j++) if (curElem.options[j].selected) theData = theData + optNameStr + '='
+ escape(curElem.options[j].value) + '&';//当页面里有dropdownlist时,还有这里的编码也要处理 } else if ( (type != "checkbox" && type != "radio") || curElem.checked ) { theData = theData + this.EncodePostData(eName) + '=' + val + '&'; }
除此之外,还要找到如下这段代码并按注释修改:
AjaxCallObject.prototype.EncodePostData = function(data) { //由于已经使用了escape方法对postback的值进行了编码,这里不再替换“%” //wangzhen 2006-07-06 //return data.split("%").join("%25").split("=").join("%3d").
//split("&").join("%26").split("+").join("%2b"); return data.split("=").join("%3d").split("&").join("%26").split("+").join("%2b"); }
这样就解决了所有的中文乱码问题!
现在我已经把这个嵌入到资源里进行了重新编译成一个dll,点击这里可以直接下载使用。
最新版本的Google Earth前些日子已经出来了,Google Earth (Release 4 - BETA) .
与旧版相比,最新版本全面更新了卫星图片资料库,现在的图像清晰程度已经很令人惊讶了!并且支持通过创建kmz文件的方式构建三维建筑来在earth上立体展现,真是太酷了!按照Google网络日志公布的说法,"可使全球大约 1/3 的人口获得所居住街区的鸟瞰图"。
而且在新版中,地标还可以包含图片。如这个国家地理杂志的地标
看着这么清晰精美的地球,让我不禁想起Google在她的公司简介里说的:Google 的使命是整合全球范围的信息,使人人皆可访问并从中受益。她真的是在这样一步一步地走下去。Search Engine,Gmail,Google Earth,Google map,Picasa,Page Creator,Blog,Google video,Google Chart,Google Calendar甚至都有了Google Mars!! 这些产品都是在围绕这个使命来的。
也许将来的某一天,真的会发生这样的情况:你一觉醒来,Google告诉你今天可以考虑去看望一个好朋友了(Google从你们的Gmail和Chart里分析得知你好久没有跟这个朋友联系了,并且从他的blog和他发给医生的email中了解到他现在生病了),在你准备出行时,Google告诉你应该走哪条道路最为划算(Google map),当你很难回忆起你与这个朋友的最后一次约会时,Google告诉你,你们曾经在某某地方最后一次合影(Picasa),并且最后一次聊天很开心(Chart)。当你真的准备上路时,Google告诉你不要忘记欣赏沿途的美丽山景(Google Earth)。。。。。。
做Search Engine的第一人绝不是Google,mail更不是,Picasa,blog则更是收购,但Google在创意上一直都是天才!
伟大的公司总有伟大的使命和梦想,就如我们每个人。抛却我们对于这种现实的幸与不幸,至少我们可以膜拜这种伟大的梦想和为这个梦想所进行的努力!有思想的公司,仰或有思想的人,总是活得的比较好。
ps.要活得好,不是那么容易的,MS现在不也还是要争取Live吗?:)
对了,如果你在看Google Earth时打不开,就检查一下是否开启了金山词霸的屏幕取词功能,GoogleEarth也使用了这个功能,与金山词霸的冲突。

昨天要把一个联动的下拉框改成使用ajax方式的,时间紧迫就直接使用了MagicAjax0.3最新版本(支持.net2.0)的,结果死活都不行。这个应用很简单,就是有一个下拉框,然后跟一系列其它的控件,它们互相关联,根据选择的下拉框的值不同,其它控件也随之显示或隐藏。但是,在我变换选择项的时候,ajax也post数据到服务器端了,但是,始终选择的是第一项。后来,我作了一个测试,手动把10个数字逐个的加上,就ok了,但一旦转到那个复杂的页面就又不行了。然后就发现那个复杂页面的dropdownlist邦定的listitem的value值也是中文,难道是中文的问题?就尝试着把value值邦定成数字,一切 ok!估计是由于ajax post到后台数据的时候,无法解析中文编码,导致它始终选定第一项。这也是简单使用xmlhttp对象的通病了,需要对中文进行特殊处理。
一直想写一系列关于web控件的文章,说说自己的一些体会。但一直很忙,就将这些文章分解开来,形成一个个的知识点随笔了:)
我们在使用web用户控件时,经常遇到一种情况:控件需要与包含它的页面进行交互。交互的种类很多, 也分不同的层次。你可以使用viewstate,session乃至静态变量,都可以。但有些时候,当控件本身会触发回传,那么,就必须使用事件来进行处理了。说起事件,并不是说web用户控件内部的这些button或者linkbutton等触发的回传事件,而是把一个web用户控件看作是一个整体对象,它有自己的属性、方法、事件。当用户控件嵌入到页面文件时, 它的内部是隐藏的,但是,它开放自己的属性、方法、事件,当内部触发了一个回传,根据回传的情况不同,它来决定是否将这个回传通知父页面。同时,父页面能够知道该子控件能提供给它什么信息。
我们知道,使用事件,就可以将用户控件所知道的信息通过EventArgs来传递给父页面,然后父页面根据这些信息进行处理。那么,首先我们就来定一个EventArgs类。 假设这个用户控件包含了三个子控件,两个文本框,一个linkbutton,这个linkbutton触发了控件的回传事件。这个控件在回传后,应该告诉父页面它能提供这两个文本框的内容,比如时userName,password吧。我们在业务逻辑层新建一个类文件,创建EventArgs类。
然后,需要定义一个委托,来指定如何处理这个提交事件public class SubmitUserEventArgs : EventArgs { public SubmitUserEventArgs(string userName, string password) { this.UserName = userName; this.Password = password; } public string UserName; public string Password; }
public delegate void SubmitUserHandler(object sender,SubmitUserEventArgs e);
这样,我们就可以在用户控件后台代码文件里加入一个事件了。
public event SubmitUserHandler SubmitUserEvent;
事件有了,那么,在什么时候我们会向父页面抛出这个事件呢,这个可以根据具体的业务而定。现在假设当控件里的linkbutton被点击时,我们触发这个事件,那么,就可以在linkbutton的事件处理方法里,填充一个eventargs对象,然后激发这个事件:
SubmitUserEventArgs args = new SubmitUserEventArgs(tbUserName.Text, tbPassword.Text); SubmitUserEvent(this, args);
这样,当linkbutton触发页面的回传时,整个控件就会及时的通知页面了。在页面的html视图里,就可以给这个控件加一个事件处理的代码
<uc1:UserControl ID="UC1" runat="Server" OnUserSubmitEvent="UC1_Submit">uc1>
然后,我们在后台的uc1_submit事件处理里就可以这样处理了:
这样就完整的提交了整个事件。实际上,上面的过程是我为了节省篇幅,没有说明一些原因。之所以可以这样写,是由于asp.net页面加载的顺序所决定的,页面总是先加载子控件,然后才是加载页面本身的信息。 这样,就使得这个事件可以触发。protected void UC1_Submit(object sender, SubmitUserEventArgs e) { string userName = e.UserName; string password = e.Password; //以下就可以放置你需要处理的任何代码了.... }