蝈蝈俊.net

-- 用随笔来记录自己的技术感触
随笔 - 674, 评论 - 4465, 引用 - 276

导航

关于

记录自己的技术心得

标签

每月存档

最新留言

  • Tykujptn
    i'm fine good work <a href=" http://www.wikio.com/user/rumyteosemil/bio "&a...
    by Tykujptn(匿名) on 2010/3/22 23:04:04
  • Xagpcinp
    Best Site good looking <a href=" http://www.wikio.com/user/yyeabeco/bio "&a...
    by Xagpcinp(匿名) on 2010/3/22 23:04:03
  • Ypzphngo
    i'm fine good work <a href=" http://www.wikio.com/user/ufaryqyfiluj/bio "&a...
    by Ypzphngo(匿名) on 2010/3/22 23:03:59
  • auto encompass insurance
    Hi! and <a href="http://autoinsurance29u.socialgo.com">automobile in...
    by auto encompass insurance(匿名) on 2010/3/22 22:05:11
  • homeland security terror alerts
    Hello! and <a href="http://debtsettlement19x.socialgo.com">not for p...
    by homeland security terror alerts(匿名) on 2010/3/22 21:45:13
  • Fidkdgun
    Excellent work, Nice Design <a href=" http://www.wikio.com/user/yyeabeco/bio &qu...
    by Fidkdgun(匿名) on 2010/3/22 21:45:04
  • Mqxgreov
    Excellent work, Nice Design <a href=" http://www.wikio.com/user/yyeabeco/bio &qu...
    by Mqxgreov(匿名) on 2010/3/22 21:45:02
  • Wpspzvup
    real beauty page <a href=" http://www.wikio.com/user/ufaryqyfiluj/bio "&...
    by Wpspzvup(匿名) on 2010/3/22 21:45:00
  • john hancock term life insurance
    How are you? and <a href="http://lifeinsurance53s.socialgo.com">inde...
    by john hancock term life insurance(匿名) on 2010/3/22 21:25:32
  • depression amitriptyline
    Howdy, and http://aldactone2.mypublicsquare.com aldactone use and http://allegra2.mypublicsquare.com...
    by depression amitriptyline(匿名) on 2010/3/22 21:06:20

广告

【第1页/共2页,11条】
首页
前页
1

枚举类型的Flags标志使用的细节问题

枚举类型可是用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
    }
控制台打印出来的是 :

Blue
3

所以,到目前的结论是:在定义会位操做的枚举类型的时候,必须用 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,
    Green = 2,
    Blue = 4
};
    [WebMethod]
    public MultiHue GetColor()
    {
        return MultiHue.Red | MultiHue.Green | MultiHue.Black;
    }
客户端调用代码如下:
            localhost.WebService ws = new Client.localhost.WebService();
            localhost.MultiHue re = ws.GetColor();
            Console.WriteLine(re);
            Console.WriteLine((int)re);
            Console.ReadLine();
这时候控制台显示的信息是:
Black, Red, Green
7
而这时候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 {
        /// <remarks/>
        Black = 1,
        /// <remarks/>
        Red = 2,
        /// <remarks/>
        Green = 4,
        /// <remarks/>
        Blue = 8,
    }
用我们前面提到的两个知识点,就可以解释为何会这样。

posted on 2006-03-30 17:01:00 by ghj1976  评论(4) 阅读(8139)

公众级软件开发

今天公司技术部例会中,瞎扯的时候,说现在应该单独提出一种软件开发思想:“公众级软件开发思想”。

“公众级软件开发思想”  第一优先考虑的是大用户量下的用户体验。

为了照顾这个第一优先考虑,我们可以不使用严格的事务。数据设计的时候,则会使用大量的冗员设计。

典型的可以认为是“公众级软件” 的:
百度的帖吧、新浪、sohu 这些服务于数百万,甚至亿的网站.
像 CSDN 现在的设计,也应该以“公众级软件”的思想来构建。
“公众级软件”并不一定只是网站。比如电信的手机计费,这个也许也应该算作“公众级软件”。


比如为了照顾用户的体验,频繁的升级会不断出现。便利的升级是设计的时候必须考虑的。
像 CSDN 和 Donew 使用的 .text 演变来的Blog程序,每次升级,至少会半个小时访问有问题。这在“公众级软件开发”中是不可接受的。

比如现在 Sina、Sohu、CSDN 都广泛使用的静态页面技术。这个技术是典型的“公众级软件”使用的一个技术。
但实际的数据,是存储在数据库中的。如果页面错误,或者静态文件没生成,这些如果从事务角度来看,是不遵循事务想法的。但是为了照顾我们前面提到的第一优先考虑,我们牺牲了这部分事务。

所以说“公众级软件”有太多的跟其他软件开发不一样的设计思想。它应该单独提炼出来一套开发方法和思想。

公众级软件开发跟企业级软件开发还是有很多不一样的。
比如前面提到的事务的处理。

暂时只想到这些,以后有啥想法再补充。

注:以上只是开会时候的瞎扯,可能没有想的比较深入。可能有些想法深入想下去会有问题的。

posted on 2006-03-17 20:31:00 by ghj1976  评论(6) 阅读(6529)

ASP.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 on 2006-03-16 15:31:00 by ghj1976  评论(9) 阅读(8731)

小心使用 HttpSessionState.Abandon 方法

一旦调用 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 on 2006-03-16 11:02:00 by ghj1976  评论(5) 阅读(7253)

ASP.Net Development Server 开发站点的问题。

中文操作系统下,比如我们有这样一个 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 on 2006-03-14 18:42:00 by ghj1976  评论(11) 阅读(6978)

千万别钻 OO设计上的死牛角

最近在做CSDN新论坛的设计,我就走了OO设计上的死牛角了。一度头大的不知所以然。下面来看我所走的弯路,希望对大家有所帮助。

 

先说功能需求

我们有这样的需求:
论坛由很多具体论坛组成。对于某个具体论坛来说,它是下述功能的组合,可能是其中一个功能的组合,也可能是其中几个功能的组合,不过确定组合后,有哪些组合就很少会发生变化,这些功能包括:

积分制、勋章制、贴图、帖链接、可以发投票帖 等等......

每个具体论坛,上述功能组合都可以不同。

 

简单来看我走的死牛角:

以论坛帖子类的设计为例。

不论用上述那些功能组合,一个帖子类,当然会有一个基类,这个基类包含最最基本的帖子信息,比如帖子编号、标题、发帖者等等。

对于 A 论坛,它选择了使用积分制功能,则A 论坛的帖子类应该还包括一个帖子分数的字段来记录跟积分制有关的信息。

对于B论坛,它选择了使用贴图功能,则B论坛的帖子类应该还包含一个字段,来记录相关的图片链接。

对于C论坛,它选择了同时使用积分制和贴图功能,则C论坛的帖子类应该还包含上述两个字段。

………………….

我们会有很多种组合。非常非常多。

 

如果我们用每个论坛实现一个派生自基类帖子类的子类,问题会是:组合太多了。而且以后丰富功能的时候,每新增一个功能,需要新增的子类会不可想象。

如果使用一个超级类,把所有功能都封装到一个类来。每个功能涉及的属性都有默认值。

则会给这个类的使用者带来很多意想不到的问题:

因为这个类相关的内部逻辑可能是开发人员A设计的。而使用者会是开发人员B

某种情况可能会需要对这个超级类的123三个属性给值。另外一种情况则…..  之前有多少种组合,这里可能就有多少种情况。

让开发人员B熟悉这么多种组合,很容易啥时候就出问题。复杂,太复杂了。

……………………………………

 

上面就是我陷入的死牛角。

 

解决方法:

一、如果OO设计上出现困惑,先不要考虑OO的设计,先考虑数据库的设计,看你数据表是如何设计的。你完全可以把数据表的结构映射到OO的设计上来。

二、如果OO设计上出现困惑,先不要考虑OO的设计,先考虑界面的设计,然后从界面的功能转到OO的设计上来。

 

这里不是说OO不好,而是由于还没有对这方面的抽象习惯过来,通过对整个流程的思考,会帮助你构造好的OO类。

就象模式一样,也是别人经过很多实践得出来的,一般都叫做refactor to patterns,即对自己的编码反复重构,最后这些编码就成了模式,或与模式相似。

不要硬套OO或者模式设计。

 

对于我这里的设计,

数据库上存储帖子信息,显然是可不管你每个论坛使用了哪些功能,而是认为所有功能你都使用了,对于没使用的功能,则认为对应的字段使用的是默认值。

不论用那种组合论坛,因为他们界面展示上完全不一样,每一套功能组合,我们都需要提供一套页面模版和接受读取参数功能来处理。这样其实组合方式并不是多得不可接受,仍然是可接受的。

 

想明白上述两点,设计就很简单的,就不会过度设计,钻OO设计的牛角了。

posted on 2006-03-13 11:33:00 by ghj1976  评论(32) 阅读(8537)

Web Services and C# Enums

出处:http://ikriv.com:8765/en/prog/info/dotnet/WebServices_and_Enums.html

由于怕链接失效,特Copy备份到这里

Web Services and C# Enums

Web Service Transparency

.NET support for web services is excellent in creating illusion of transparency. General process is quite straightforward:

  • On the server we create a web service, decorating publicly visible methods with [WebMethod] attribute.
  • On the client we add a web reference to the service, and proxy code is automatically generated for us by VIsual Studio. We can then call web service methods almost as if they were local methods.

All arguments and return values get magically XML-serialized, transmitted to the peer, and de-serialized to something very close to the original form. Ideally, this whole process should be automatic and seamless.

Imperfect Transparency of Enums

It turns out that enums are not as transparent as we'd like them to be. There are three sticky issues:

  1. If server-side code declares an enum and assigns specific numeric values to its members, these values will not be visible to the client.
  2. If server-side code declares a [Flags] enum with "compound" mask values (as in White = Red|Green|Blue), it is not properly reflected on the client side.
  3. If server or client transmits an "illegal" value which is outside of the scope of the enum, it causes an exception in XML de-serializer on the other side.

Numeric Values Are Not Preserved

If we have server-side definition like this:

enum StatusCode
{
    Success = 200,
    NotFound = 404,
    Denied  = 401
}

it is translated to client-side definition like this:

enum StatusCode
{
    Success = 1,
    NotFound = 2
    Denied  = 3
}

Corresponding WSDL looks as follows:

<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>

As one can see, there is no mension of numeric values in the WSDL. Proxy code generator on the client side does not have access to anything but WSDL. Therefore, it does not have a chance to get numeric values of enum members.

An important side effect of this phenomenon is that the relative order of enum members may not be preserved. For instance, in the example above, expression
(StatusCode.NotFound > StatusCode.Denied)

is true on the server, and false on the client.

Relationships Between [Flags] Masks May Be Broken

Server-side declaration:

[Flags]
enum UserRights
{
	Read = 16,
	Write = 256,
	Delete = 1024,
	AllAccess = Read | Write | Delete
}

Client-side declaration (some insignificant decoratios removed):

[Flags]
enum UserRights
{
   Read = 1,
   Write = 2,
   Delete = 4,
   AllAccess = 8
}

Corresponding WSDL:

<s:simpleType name="UserRights">
    <s:restriction base="s:string">
        <s:enumeration value="Read"/>
        <s:enumeration value="Write"/>
        <s:enumeration value="Delete"/>
        <s:enumeration value="AllAccess"/>
    </s:restriction>
</s:simpleType>

Therefore, on the client UserRights.AllAccess lost its relationship to other user right values. On the server expression
(UserRights.AllAccess & UserRights.Read) != 0
is true, while on the client it is false.

This can lead to disastrous consequences.

Out-Of-Range Values Cause Exception on Receiving End

The following server-side code:

enum Test
{
    SomeValue = 1
}

[WebMethod]
public Test GetValue()
{
   return (Test)512;
}

will cause "invalid XML document" exception on the client side when reading GetValue() response. This exception is related to how XML serializer works with enums. "Legal" values are transmitted as text. E.g. value of 1 would be transmitted as <Test>SomeValue</Test>. For [Flags] enums multiple text strings are transmitted to indicate concatenation of several masks, e.g. <UserRights>Read Write</UserRights>. However, out-of-range values are transmitted as stringified integers, e.g. <Test>512</Test>. These integers are not understood at the receiving end and cause exception.

Controlling Generated XML

It seems that .NET framework does not give you much leeway in controlling XML generated for enums. In particular, constructs like :

[XmlElement(typeof(int))]
enum MyEnum
{
    ...
}

or

[XmlElement(DataType="integer")]
enum MyEnum
{
    ...
}

do compile, but fail miserably at run-time.

One useful attribute is [XmlEnum], which allows to change names of enum members. As we mensioned before, enum members are transmitted as literal strings. Therefore, if one has flags enum like this:

[Flags]
enum MyMask
{
    VeryVeryLongFlagNameWillBeTransmittedToClient,
    AnotherQuiteLongFlagNameAlongTheFirstOne,
    EtCeteraEtCetera
}

generated XML can get quite verbose. To prevent this, transmitted literal strings may be changed using [XmlEnum]:

[Flags]
enum MyMask
{
    [XmlEnum("VeryLong")] VeryVeryLongFlagNameWillBeTransmittedToClient,
    [XmlEnum("Another")]  AnotherQuiteLongFlagNameAlongTheFirstOne,
    [XmlEnum("EtCetera")] EtCeteraEtCetera
}

Conclusion

Extra caution must be excercised when transmitting enums over web service boundary. Behavior of XML serializer is not always straightforward for enums, and sometimes can cause serious incompatibilities between client and server. To ensure correct operation of software, one must keep in mind its limitations. If numeric values need to be preserved across the wire, they must be transferred as integers, not enums. In this case, however, client must have ad-hoc knowledge regarding what value means what.

.NET framework provides limited means of manipulating XML generated for enums. In particular, we were unable to find an attribute that would allow to automatically transmit enum as int.

posted on 2006-03-08 14:46:00 by ghj1976  评论(0) 阅读(1554)

WEB Service 中使用 Enum 类型。

先看例子
比如服务器段我们有这样一个定义
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# Enums
http://ikriv.com:8765/en/prog/info/dotnet/WebServices_and_Enums.html

posted on 2006-03-08 14:44:00 by ghj1976  评论(7) 阅读(6860)

ASP中操作UTF-8格式的文件

注意:这里说的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 With
Set 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 FAQ
http://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 on 2006-03-08 11:42:00 by ghj1976  评论(5) 阅读(8258)

Lutz Roeder's .NET Reflector

.NET Reflector 是一个只有 548 KB 的.net 类浏览工具。
它可以读取存储在 .net 应用程序 中的 metadata、IL 指令、资源和XML文档。
并可以把这些信息,以IL、C#、VB.net 、Delphi、MC++、Chrome 这些语言的方式
来展示其中的功能.

它同时支持 .net 1.0 1.1 2.0

下面就是一个它运行效果的截图:

Lutz Roeder's .NET Reflector   效果图 
它的下载地址请看:
http://www.aisto.com/roeder/dotnet/
它的一些插件地址请看:
http://workspaces.gotdotnet.com/reflector

我的上篇Blog,分析如何用Mock对象,就是借用了这个工具,分析出了HttpSessionState类构造函数的具体接口,进而可以用反射方式构造出HttpSessionState类的实例。

posted on 2006-03-03 09:09:00 by ghj1976  评论(8) 阅读(10746)

【第1页/共2页,11条】
首页
前页
1

Powered by: Joycode.MVC引擎 0.5.2.0