RSS 2.0 Feed
2006-03 Entries
摘要:枚举类型可是用Flags 标志,表示这些枚举类型可以作为位域(即一组标志)处理。 比如下面的枚举类型:    [Flags]     enum MultiHue : short    {        Black = 0,        Red = 1,        Green = 2,        Blue = 4    }; 这里用 2 的幂(即 1、2、4、8 等)定义枚举常量。这意味着组合的枚举常量中的各个标志都不重叠。 但是,要注意的是:在当前程序中,如果你没有定义这些枚举类型的值,则默认系统给你的定义可不是 2 的幂,而是从0开始,每次累加1。 比如下面的代码:    class Program    {        static void Main(string[] args)        {            Console.WriteLine(MultiHue.Blue);            Console.WriteLine((int)MultiHue.Blue);            Console.ReadLine();        }    }     [Flags]    enum MultiHue : short    {        Black,        Red,        Green,        Blue    }控制台打印出来的是 : Blue3 所以,到目前的结论是:在定义会位操做的枚举类型的时候,必须用 2 的幂(即 1、2、4、8 等)定义枚举常量。不可以不附值。而如果你的这个枚举类型被 Web Service 作为一个方法的参数使用了。在客户端VS2005 系统自动会给你的MultiHue 附值。客户端会产生了下面的代码,而不管你服务器端定义的枚举数字值是多少。:     [System.FlagsAttribute()][System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "2.0.50727.42")]    [System.SerializableAttribute()][System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/")]    public enum MultiHue    {        Black = 1,        Red = 2,        Green = 4,        Blue = 8    }; 注意,不论我们服务器段是否给 ,每个枚举类型附值,客户端VS2005替你产生的代码都是上述方式。这时候你会发现,每个枚举类型的数字值可能会发生变化了。 原因就是 枚举类型的序列化是序列化成了文本,而不是数字。由于客户端和服务器端没有数字的传递,当然客户端和服务器端的枚举项的值当然有很大的可能会不一样了。所以这里的结论是:如果Web Service用到枚举类型,一定不要用枚举类型的数字值,因为服务器端和客户端会不一样。参考:http://ikriv.com:8765/en/prog/info/dotnet/WebServices_and_Enums.html 综上所述。 如果你希望对枚举类型进行位操作, 比如注意以下两点:1、在定义的时候,必须用 2 的幂(即 1、2、4、8 等)定义枚举常量。不可以不附值。2、如果Web Service用到枚举类型,一定不要用枚举类型的数字值,因为服务器端和客户端会不一样。 再看一个稍稍复杂的例子,用上面的知识点,就可以解释后面的例子为啥会这样。比如有这样一个Web Service。[Flags]public enum MultiHue{    Black = 8,    Red = 1,   ......[阅读全文]

posted @ | Feedback (4) | Filed Under [ .net 编程心得 ]

摘要:今天公司技术部例会中,瞎扯的时候,说现在应该单独提出一种软件开发思想:“公众级软件开发思想”。 “公众级软件开发思想”  第一优先考虑的是大用户量下的用户体验。 为了照顾这个第一优先考虑,我们可以不使用严格的事务。数据设计的时候,则会使用大量的冗员设计。 典型的可以认为是“公众级软件” 的:百度的帖吧、新浪、sohu 这些服务于数百万,甚至亿的网站.像 CSDN 现在的设计,也应该以“公众级软件”的思想来构建。“公众级软件”并不一定只是网站。比如电信的手机计费,这个也许也应该算作“公众级软件”。 比如为了照顾用户的体验,频繁的升级会不断出现。便利的升级是设计的时候必须考虑的。像 CSDN 和 Donew 使用的 .text 演变来的Blog程序,每次升级,至少会半个小时访问有问题。这在“公众级软件开发”中是不可接受的。 比如现在 Sina、Sohu、CSDN 都广泛使用的静态页面技术。这个技术是典型的“公众级软件”使用的一个技术。但实际的数据,是存储在数据库中的。如果页面错误,或者静态文件没生成,这些如果从事务角度来看,是不遵循事务想法的。但是为了照顾我们前面提到的第一优先考虑,我们牺牲了这部分事务。 所以说“公众级软件”有太多的跟其他软件开发不一样的设计思想。它应该单独提炼出来一套开发方法和思想。 公众级软件开发跟企业级软件开发还是有很多不一样的。比如前面提到的事务的处理。暂时只想到这些,以后有啥想法再补充。 注:以上只是开会时候的瞎扯,可能没有想的比较深入。可能有些想法深入想下去会有问题的。...[阅读全文]

posted @ | Feedback (6) | Filed Under [ .net 编程心得 技术随笔 ]

摘要:

如果你装了杀毒软件,比如我装的 McAfee VirusScan。
他们默认就阻滞程序发送邮件,甚至包括WEB程序,也会阻滞。而我以前只碰到过这个杀毒软件阻滞Windows程序,今天竟然发现WEB程序也阻滞了。

你用程序发送邮件时候,可能会收到 "无法连接到远程服务器" 、"您的主机中的软件放弃了一个已建立的连接。"的异常。

要解决这个问题,就是让杀毒软件放弃对这个程序的限制,以McAfee VirusScan为例,就是要把你的程序名放到例外名单中。如下图:
McAfee 端口限制修改页 
如果我们WEB 程序是在 VS2005 自带的  ASP.net Development Server 中运行,则这里的例外程序就是:WebDev.WebServer.Exe

如果是在 IIS 6 中进行的,则通常是 w3wp.exe。

IIS 5 通常是 aspnet_wp.exe

参考:http://blog.joycode.com/ghj/archive/2004/10/22/36274.aspx...[阅读全文]

posted @ | Feedback (9) | Filed Under [ .net 编程心得 网站开发管理相关内容 ]

摘要:一旦调用 HttpSessionState.Abandon 方法,当前会话不再有效,同时会启动新的会话。Abandon 使 SessionStateModule.End 事件被引发。发送下一次请求后将引发新的 SessionStateModule.Start 事件。 所以,如果在对你ASP.net页面的一次请求中,有类似下面的两行代码:不论在不在同一个函数中。不论先后顺序。 ......HttpContext.Current.Session.Abandon();.........HttpContext.Current.Session["ClientKey"] = "aaaaaaa"; 新的页面,你是无法获得  Session["ClientKey"] 的值的. 最近我碰到的一个bug,就是 在一个封装很深的组件中,封装了 HttpContext.Current.Session.Abandon() 方法。造成读不出Session的问题....[阅读全文]

posted @ | Feedback (5) | Filed Under [ .net 编程心得 网站开发管理相关内容 ]

摘要:中文操作系统下,比如我们有这样一个 ASP.net 页面 Default.aspx它的功能超简单,只有下面这些功能: protected void Page_Load(object sender, EventArgs e){   Response.Write(Request.RawUrl);   Response.Write("");   Response.Write(Request.QueryString["aaa"]);} 这个页面在 ASP.Net Development Server 开发站点的时候,单独请求如下页面: http://localhost:8186/WebSite2/Default.aspx?aaa=哈哈&bb=c123 返回: /WebSite2/Default.aspx?aaa=&bb=c123 中间的中文字符自动被干掉了。同样的程序,在 IIS 上,则没有任何问题。所以在作程序的时候,要注意这点。可能开发环境有问题,运行环境没问题。 另外,在中文操作系统中,VS2005 默认创建一个Html页面,是 ASCI码的文件,默认创建一个 ASPX 页面,是UTF-8编码的文件。这两个文件之间如果有中文参数值传递,可能就会导致乱码出现。...[阅读全文]

posted @ | Feedback (11) | Filed Under [ .net 编程心得 技术随笔 ]

摘要:最近在做CSDN新论坛的设计,我就走了OO设计上的死牛角了。一度头大的不知所以然。下面来看我所走的弯路,希望对大家有所帮助。   先说功能需求 我们有这样的需求:论坛由很多具体论坛组成。对于某个具体论坛来说,它是下述功能的组合,可能是其中一个功能的组合,也可能是其中几个功能的组合,不过确定组合后,有哪些组合就很少会发生变化,这些功能包括: 积分制、勋章制、贴图、帖链接、可以发投票帖 等等...... 每个具体论坛,上述功能组合都可以不同。   简单来看我走的死牛角: 以论坛帖子类的设计为例。 不论用上述那些功能组合,一个帖子类,当然会有一个基类,这个基类包含最最基本的帖子信息,比如帖子编号、标题、发帖者等等。 对于 A 论坛,它选择了使用积分制功能,则A 论坛的帖子类应该还包括一个帖子分数的字段来记录跟积分制有关的信息。 对于B论坛,它选择了使用贴图功能,则B论坛的帖子类应该还包含一个字段,来记录相关的图片链接。 对于C论坛,它选择了同时使用积分制和贴图功能,则C论坛的帖子类应该还包含上述两个字段。 …………………. 我们会有很多种组合。非常非常多。   如果我们用每个论坛实现一个派生自基类帖子类的子类,问题会是:组合太多了。而且以后丰富功能的时候,每新增一个功能,需要新增的子类会不可想象。 如果使用一个超级类,把所有功能都封装到一个类来。每个功能涉及的属性都有默认值。 则会给这个类的使用者带来很多意想不到的问题: 因为这个类相关的内部逻辑可能是开发人员A设计的。而使用者会是开发人员B。 某种情况可能会需要对这个超级类的1、2、3三个属性给值。另外一种情况则…..  之前有多少种组合,这里可能就有多少种情况。 让开发人员B熟悉这么多种组合,很容易啥时候就出问题。复杂,太复杂了。 ……………………………………   上面就是我陷入的死牛角。   解决方法: 一、如果OO设计上出现困惑,先不要考虑OO的设计,先考虑数据库的设计,看你数据表是如何设计的。你完全可以把数据表的结构映射到OO的设计上来。 二、如果OO设计上出现困惑,先不要考虑OO的设计,先考虑界面的设计,然后从界面的功能转到OO的设计上来。   这里不是说OO不好,而是由于还没有对这方面的抽象习惯过来,通过对整个流程的思考,会帮助你构造好的OO类。 就象模式一样,也是别人经过很多实践得出来的,一般都叫做refactor to patterns,即对自己的编码反复重构,最后这些编码就成了模式,或与模式相似。 不要硬套OO或者模式设计。   对于我这里的设计, 数据库上存储帖子信息,显然是可不管你每个论坛使用了哪些功能,而是认为所有功能你都使用了,对于没使用的功能,则认为对应的字段使用的是默认值。 不论用那种组合论坛,因为他们界面展示上完全不一样,每一套功能组合,我们都需要提供一套页面模版和接受读取参数功能来处理。这样其实组合方式并不是多得不可接受,仍然是可接受的。   想明白上述两点,设计就很简单的,就不会过度设计,钻OO设计的牛角了。...[阅读全文]

posted @ | Feedback (32) | Filed Under [ .net 编程心得 技术随笔 网站开发管理相关内容 ]

摘要:先看例子比如服务器段我们有这样一个定义enum StatusCode{    Success = 200,    NotFound = 404,    Denied  = 401} 我们在调用 WebService 的客户端可能就成了这样:enum StatusCode{    Success = 1,    NotFound = 2    Denied  = 3} 所以这时候可一定不能用这样的编码了StatusCode code = (StatusCode)200; 上面方式的WSDL 是类似这样的:<s:simpleType name="StatusCode">    <s:restriction base="s:string">        <s:enumeration value="Success"/>        <s:enumeration value="NotFound"/>        <s:enumeration value="Denied"/>    </s:restriction></s:simpleType>所以会出现客户端和服务器段的数字ID不一样。 正好这个问题,一个老外已经描述的很详细了,我就不废话了,请参看后面链接: Web Services and C# Enumshttp://ikriv.com:8765/en/prog/info/dotnet/WebServices_and_Enums.html...[阅读全文]

posted @ | Feedback (7) | Filed Under [ 技术随笔 ]

摘要:注意:这里说的ASP可不是ASP.net。ASP由于是一种古老的语言,它的一些功能对UTF-8支持非常差。比如,你想生成一个UTF-8格式的文件,使用常用的 Scripting.FileSystemObject 对象就不行。 Scripting.FileSystemObject 对象创建文件的函数,是下面方式:FileSystemObject.CreateTextFile(filename[,overwrite[,unicode]]) 其中的 unicode 属性是这样描述的: 可选项。Boolean 值指明是否以 Unicode 或 ASCII 文件格式创建文件。如果以 Unicode 文件格式创建文件,则该值为 True;如果以 ASCII 文件格式创建文件,则该值为 False。如果省略此部分,则假定创建 ASCII 文件。 我们是无法用这个函数来创建UTF-8格式文件的。这时候,我们可以使用 ADODB.Stream 对象,使用方法见下面: Set objStream = Server.CreateObject("ADODB.Stream")    With objStream    .Open    .Charset = "utf-8"    .Position = objStream.Size    .WriteText=str    .SaveToFile server.mappath("/sitemap.xml"),2     .Close    End WithSet objStream = Nothing 附:ASCII 、Unicode 、 UTF-8 介绍:ASCII 是一种字符集,包括大小写的英文字母、数字、控制字符等,它用一个字节表示,范围是 0-127。 由于 ASCII 表示的字符非常有限,各个国家或者地区在此基础上提出了自己的字符集,比如在中国应用非常广泛的 GB2312,它为汉字提供了编码,用两个字节表示。 这些字符集之间互不兼容,相同的数字可能表示不同的字符,为信息交流带来了麻烦。Unicode 是一种字符集,它将世界上的所有字符映射成一个唯一的数字(code point),比如字母 a 对应的数字 0x0041。目前 Unicode 还处于发展中,它所包容的字符越来越多。 在将 Unicode 表示的字符进行存储时,还需要一定的编码方式,比如 UCS-2,它用两个字节来表示 Unicode 编码的字符。而 UTF-8 是 Unicode 字符集的另外一种编码方式,它是变长度的,最多 6 个字节,小于 127 的字符用一个字节表示,与 ASCII 字符集的结果一样,因而具有非常好的兼容性,ASCII 编码下的英语文本不需要修改就可以当作 UTF-8 编码进行处理,应用非常广泛。 UTF-8 and Unicode FAQhttp://www.linuxforum.net/books/UTF-8-Unicode.html ADODB.Stream组件Charset属性值http://www.5iya.com/blog/post/adodb_stream_charset_value.asp 用ADODB.Stream代替FSO读取文本文件http://www.99net.net/study/page/1025101521.htm...[阅读全文]

posted @ | Feedback (5) | Filed Under [ 技术随笔 ]

摘要:.NET Reflector 是一个只有 548 KB 的.net 类浏览工具。它可以读取存储在 .net 应用程序 中的 metadata、IL 指令、资源和XML文档。并可以把这些信息,以IL、C#、VB.net 、Delphi、MC++、Chrome 这些语言的方式来展示其中的功能. 它同时支持 .net 1.0 1.1 2.0 下面就是一个它运行效果的截图:  它的下载地址请看:http://www.aisto.com/roeder/dotnet/它的一些插件地址请看:http://workspaces.gotdotnet.com/reflector我的上篇Blog,分析如何用Mock对象,就是借用了这个工具,分析出了HttpSessionState类构造函数的具体接口,进而可以用反射方式构造出HttpSessionState类的实例。...[阅读全文]

posted @ | Feedback (8) | Filed Under [ 技术随笔 ]

摘要:先说场景。为了保证业务逻辑跟页面展示分开。我们在开发WEB项目的时候,一般应用逻辑跟ASPX页面是分离的项目。应用逻辑一般会是一个DLL组件项目。如果这个组件项目中A方法使用了Session、Cookie等信息的读写,则这个方法就很难写单元测试。但并不是写不出来,要写出来大致思路如下: 目标: 构建一个测试的环境,把需要的Session、Cookie等信息初始化好。 这样才好做测试。而且这个构建的环境,不应该影响实际功能代码的编写。 具体实现来说: 初始化的时候,使用了 HttpWorkerRequest 抽象类的派生类 SimpleWorkerRequest 来实现初始化。 但是 SimpleWorkerRequest 功能太简单了,不具备Session的功能。 这时候我们就需要用 Mock 技术来构造一个可以满足我们需要的环境的原理: 这个Mock的机制如下: 用反射机制,构造一个 HttpSessionState 对象(HttpSessionState类的构造函数是internal 的),然后把这个对象跟SimpleWorkerRequest 对象捆绑。 这样我们就可以 构建了一个满足自己需要的环境了,即 MockHttpContext 类。 具体实现的原理请参看: http://www.jasonbock.net/JB/Default.aspx?blog=entry.161daabc728842aca6f329d87c81cfcb 但是那里是 .net 1.1 下的做法, .net 2.0 下很多发生变化了,后面整理的代码是 .net 2.0下该如何用的代码。 后面的演示把代码写的很简单,实际应用逻辑可能会很复杂。 比如我们在组件中有这样的一个方法,获得当前登录用户ID:public static int GetMemberID(){    string MemberID = HttpContext.Current.Session["MemberID"].ToString();    return Convert.ToInt32(MemberID);} 我们下面就来考虑如何对这个方法进行单元测试。 因为是组件项目,我们无法使用 Visual Studio Team System 的ASP.net单元测试。我们下面就用模拟的方式来做这个单元测试。简单来说,就是我们需要构造一个HttpContext对象 ,然后在给其中的Session附值。然后再把它指定到 System.Web.HttpContext.Current 中。 先看一些基础知识:有关在单元测试中使用HttpContext 的方法,请看下面的链接Unit testing with HttpContext http://weblogs.asp.net/jeff/archive/2004/05/31/145111.aspx 模拟的代码简单来说就是: System.IO.TextWriter tw = new System.IO.StringWriter();System.Web.HttpWorkerRequest wr = new System.Web.Hosting.SimpleWorkerRequest("/webapp", "c:\\inetpub\\wwwroot\\webapp\\", "default.aspx", "", tw);System.Web.HttpContext.Current = new System.Web.HttpContext(wr); 但是需要注意的是,如果我们再简单的增加下面一行,虽然编译没有错误,但是执行不通过。System.Web.HttpContext.Current.Session["MemberID"] = 1245;因为SimpleWorkerRequest并没有封装有关Session的功能。 这样我们需要作更多的东西。这就要用到Mock技术.相关资料请参考:Adding Session State to a Mock HttpContext Objecthttp://www.jasonbock.net/JB/Default.aspx?blog=entry.161daabc728842aca6f329d87c81cfcb 但是上面连接是给的.net 1.1下的做法。.net 2.0 下 HttpSessionState函数的构造函数发生了变化。那里的代码很多要发生变化。 .net 2.0 下 HttpSessionState 的构造函数变成了下面方式:internal HttpSessionState(IHttpSessionState container){      this._container = container;} 这样我们首先要实现一个 IHttpSessionState 接口的对象。实现这个接口的范例代码请看:http://msdn2.microsoft.com/zh-cn/library/system.web.sessionstate.ihttpsessionstate.aspx其中有一个 MySessionState 就是实现了这个接口。这个类在我们后面会被用到。 根据上述改变,我们根据 http://www.jasonbock.net/JB/Default.aspx?blog=entry.161daabc728842aca6f329d87c81cfcb的知识点,作的 .net 2.0 下的......[阅读全文]

posted @ | Feedback (13) | Filed Under [