2006年11月所有随笔

PCVCBlog 加了个编辑器(FreeTextBox)

  挑了好几个编辑器,最终于还是用 FreeTextBox(FTBv3-1-6),可惜不是开源的了,功能还是挺多的,应该也是很成熟的产品了。选编辑器,我一直寻找简单实用,最好是开源的,找了很久,都不是很理想,心想,等以后自己也做个简单实用编辑器,现在就暂时用这个吧,没有编辑器写 Blog 确实很不方便。

FreeTextBox 3.0 - click for demos
FreeTextBox 3.0 demo image

PCVCBlog Web 部份转向 Web Application Project

  PCVCBlog Web 项目从 WebSite 模式转向了 Web Application Project,WAP 确实方便多了,整个项目只包含在一个程序集中,不像 WebSite 模式,一个 .CS 文件要一个程序集。

  其实上个星期早已将 Web Application Project 在中文 VS 2005 下跑了,只是这个星期在广州呆了一个星期,主要是公司的项目外包在广州时代财富,交易那块时代财富没有业务经验,只好上去协助协助,还有加上支付宝这块。

  现在终于把 PCVCBlog 的开发环境及项目安排定了下来,但还有很多要研究的地方,不过对于偶这种新手来说已经是个很好的开始了。

  PCVCBlog 包括:

    PCVC.Web 项目:Web
    PCVC.Blogs 项目:博客
    PCVC.Components 项目:全局共用组件
    PCVC.Controls 项目:全局共用控件
    PCVC.SqlDataProvider 项目:数据库

让 Web Application Project 支持中文 VS 2005[已过时]

  众所周知,Visual Studio 2005 的 Web Site 模式,实在有诸多不方便。于是 MS 推出了 Web Application Project,可以同VS 2003 一样,将网站当做一个项目来做,目前 VS 2005 Web Application Project V1.0 已经发布很久了,但还不能支持 VS 2005 中文版,这让像本人一样用惯了中文版(可悲)的朋友来说,还是只有羡慕的份。经过几番周折,终于找到临时的解决方法,也许是最愚蠢的方法吧:

  1. 先装好英文版,选自定义安装,最好是选安装一种语言工具(C#)就行,其它都不要装,反正要卸载的:)。

  2. 安装补丁 VS80-KB915364-X86-ENU.exe。

  3. 安装 WebApplicationProjectSetup.msi。

  4. 卸载英文版。

  5. 安装中文版,完毕。

  整个过程不用重新启动,只要安装英文版时组件不要选择太多,工程还不算大,谁让你喜欢用中文呢。


  注:VS 2005 SP1 已包含 Web Application Project

SQL Server 2005 分页功能

SELECT TOP 10 * FROM bbs_user ORDER BY jointime

SELECT * FROM (select *, ROW_NUMBER() Over(order by jointime) as rowNum from bbs_user) as bbs_user where rowNum between 3 and 6;

第二条语句是获取中间的第 3 4 5 6 条记录!

对字符串进行 MD5 加密

    在 asp 时代,对字符串进行 MD5 方法,均使用网上流行的 MD5 加密函数。

    用 .net 编写程序时,则可以使用 .Net 自带的 MD5 类,MD5 类在于 System.Security.Cryptography 命名空间里,该命名空间提供加密服务,包括安全的数据编码和解码,以及许多其他操作,例如散列法、随机数字生成和消息身份验证。其中包括 HashAlgorithm、MD5、MD5CryptoServiceProvider 等类。

    MD5 类继承于加密哈希算法基类(HashAlgorithm),表示 MD5 哈希算法的所有实现均从中继承的抽象类。

    一般地,使用 MD5 加密服务提供程序类(MD5CryptoServiceProvider)来对字符串进行 MD5 加密:

    public static string Md5(string strPassword, int code)
    {
        MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
        if (code == 16)
            return BitConverter.ToString(hashmd5.ComputeHash(Encoding.Default.GetBytes(strPassword))).Replace("-", "").ToLower().Substring(8, 16);
        else
            return BitConverter.ToString(hashmd5.ComputeHash(Encoding.Default.GetBytes(strPassword))).Replace("-", "").ToLower();
    }

    如果是用于 Web 的,还可以用 System.Web.Security.FormsAuthentication 类的 HashPasswordForStoringInConfigFile 方法:

    public static string Md5(string strPassword, int code)
    {
        if (code == 16)
            return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(strPassword,"MD5").ToLower().Substring(8, 16);
        else
            return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(strPassword,"MD5").ToLower();
    }

CommunityServer 读取 Blog 分析(一)

    首先,会建立 AggregatePostList 类的一个实例,先执行 AggregatePostList 类的构造函数,并执行类中有赋初值的所有语句,因为 AggregatePostList 是继承于 WeblogBaseTemplatedWebControl 类,而 WeblogBaseTemplatedWebControl 类又继承于 TemplatedWebControl 类,而 TemplatedWebControl 类又继承于 WebControl 类,且实现 INamingContainer 接口,所以,严格的说应该一开始是执行这四个类的构造函数(默认的构造函数,即没有参数的构造函数)和这四个类中所有有赋初值的语句。且执行顺序是从基类开始!好,第一个,WebControl的构造函数,输出HTML元素<span id="xxx"></span>,接下来看 TemplatedWebControl 类,该类没有构造函数,再接着看 WeblogBaseTemplatedWebControl 类的构造函数,只有一句:

    _currentUser = CSContext.Current.User;

    获取当前浏览者的各方面信息,详细见 CommunityServer.Components.User 类。

    最后看 AggregatePostList 类的构造函数,哈,空的,过!

    在这个过程中,要注意各类中赋初值的语句,因为有一些信息不知不觉已经初始化,而在后面分析代码却不知是从何而来。

    接下来,应该转到 AggregatePostList 类的 OnLoad 函数,第一句:

    base.OnLoad(e);

    此方法通知服务器控件应执行关联页的每个 HTTP 请求的共同操作,例如设置数据库查询。在页生存期的此阶段,创建并初始化层次结构中的服务器控件,还原视图状态,并且窗体控件反映客户端数据(这一段理解不是很深,不敢多写)。下一句:

    this.EnsureChildControls();

    EnsureChildControls 函数是System.Web.UI.Control类的一个protected virtual void 方法(虚拟方法,提供默认实现)。代码如下:

    protected virtual void EnsureChildControls()
    {

        if (!this.ChildControlsCreated && !this.flags[0x100])
        {
            this.flags.Set(0x100);
            try
            {
                this.ResolveAdapter();

                if (this._adapter != null)
                {
                    this._adapter.CreateChildControls();
                }
                else
                {
                    this.CreateChildControls();
                }
                this.ChildControlsCreated = true;
            }
            finally
            {
                this.flags.Clear(0x100);
            }
        }
    }

    MSDN:

    功能:确定服务器控件是否包含子控件。如果不包含,则创建子控件。

    该方法首先检查 ChildControlsCreated 属性的当前值。如果此值为假,则调用 CreateChildControls 方法。其中:

    ChildControlsCreated 属性:设置或指示是否已创建服务器控件的子控件。

    CreateChildControls 方法:一个 virtual(虚拟)方法,没提供默认实现,一般由开发复合服务器控件或模板服务器控件的用户重写此方法,用于创建自定义控件的子控件。WebControl 类没有重新此方法,那么其它三个类()中必定有一个重写此方法。确实,在 TemplatedWebControl 类就有如下的定义:

    protected override void CreateChildControls()
    {
        Controls.Clear();

        // 1) String Control

        Boolean _skinLoaded = LoadTextBasedControl();

        // 2) Inline Template

        if ( !_skinLoaded )
        {
            _skinLoaded = LoadSkinTemplate();
        }

        // 3) Themed Control

        if (!_skinLoaded)
        {
            _skinLoaded = LoadThemedControl();
        }

        // 4) Default Control

        if ( !_skinLoaded )
        {
            _skinLoaded = LoadDefaultThemedControl();
        }

        // 5) If none of the skin locations were successful, throw.

        if ( !_skinLoaded )
        {
            throw new CSException( CommunityServer.Components.CSExceptionType.SkinNotFound, this.GetType().ToString() );
        }

        if(_skinLoaded)
            AttachChildControls();
    }

    上面说了,CreateChildControls 方法是创建自定义控件的子控件(在此是某个 Web 用户控件)。首先,执行 Controls.Clear() 方法,从当前服务器控件的 ControlCollection 对象中移除所有控件。接着根据不同情况,调用不同的方法创建不同的控件,这些方法都以Load开头,每个方法都被设计为虚拟(virtual)方法。首先是LoadTextBasedControl() 方法,代码如下:

    protected virtual bool LoadTextBasedControl()
    {
        string text = ControlText();

        if(!Globals.IsNullorEmpty(text)) // text 为空或为 null 时 IsNullorEmpty 方法返回真。
        {//有指定 Web 用户控件名称

            Control skin = this.Page.ParseControl(text);

            skin.ID = "_";

            this.Controls.Add(skin);

            return true;
        }

        return false;
    }

    首先,执行 ControlText() 方法,该方法也被设计为虚拟方法,且默认实现是返回 null,代码如下:

    protected virtual string ControlText()
    {
        return null;
    }

    为什么要这样做呢?我认为是为了有更好的扩展性,如:我们要创建的 Web 用户控件的名称需要从数据库读取,那么就可以重写 ControlText() 方法,然后在 ControlText() 方法中从数据库读出并返回控件名称,或通过在 ControlText() 方法用其它方法返回控件名称。在此例,LoadTextBasedControl() 方法返回 false。而一旦调用某个方法创建好子控件后,其它情况将被忽略,直至调用 AttachChildControls() 方法。好,接下来分析调用 LoadSkinTemplate() 方法的情况,当用户控件有出现模板化属性的情况下将会调用 LoadSkinTemplate() 方法,模板的名称和用户控件的类的属性相关联,如 TemplatedWebControl 类就以下定义:

    public ITemplate SkinTemplate
    {
        get
        {
            return _skinTemplate;
        }
        set
        {
            _skinTemplate = value;

            ChildControlsCreated = false;
        }
    }

    private ITemplate _skinTemplate;

    说明 SkinTemplate 就是一个模板属性,在页面中就可以如下引用:

    <Blog:AggregatePostList runat="Server" id="Aggregatepostlist1" NAME="Aggregatepostlist1" EnablePaging="true">
    <SkinTemplate>
        Server control, data-binding syntax, other valid markup
    </SkinTemplate>
    </Blog: AggregatePostList>

Metabuilders.Webcontrols.Masterpages 应用的一点理解

Metabuilders.Webcontrols.Masterpages 由 4 个控件ContentContainer、Content、Region、NoBugForm组成。 ContentContainer 控件可以包含或不包含其它控件,但只能包含 Content 控件。如果包含了 Content 控件,则 Content 控件里的内容将填充一个 Region 控件,Region 控件必需声明在 ContentContainer 控件的 ThemeMasterFile 属性指定的用户用户控件里(或在该控件里有声明 ContentContainer 控件由其 MasterPageFile 指定的用户控件中--可无限循环)。在 Region 控件里可以指定默认内容,也可以不指定,但一定要声明一个 ID 和被包含的 Content 控件的 ID 相同的 Region 控件!如果包含的 Content 控件本身没有的内容,Region 控件是不会使用头尾标记中的内容的。

相关连接:http://www.learnasp.com/freebook/learn/masterpage.aspx

最最最简单的理解 .Net 程序是如何启动的

http://blog.csdn.net/abigfrog/archive/2003/06/09/12805.aspx 有感:


1. .Net 程序是一个拥有标准 PE 头和 IL(Intermediate Language) 代码的 Win32 程序

2. 要运行 .Net 程序,需要安装 .Net 运行期引擎,就是 MSCorEE.DLL (太天真了!)

3. 当运行程序时,操作系统通过 PE 文件里的入口点,判断系统是否安装 .Net Framework 并启动 .Net 运行期引擎

4. 随后将指示操作系统调用 MSCorEE.DLL 里的 _CorExeMain 函数

5. 随后 _CorExeMain 函数开始解析位于 PE 文件中的 IL 代码

6. 解析完,因为 IL 是不能被直接执行的,将指示 .Net 运行期引擎使用即时编译器将 IL 代码编译成本地 CPU 机器代码,并运行

初识 C# 委托

MSDN:
委托是一个类型,是一个定义签名的类型,即方法的返回值类型和参数列表类型。可以使用委托类型来声明一个变量,该变量可以引用与委托签名相同的所有方法。


委托仅仅是函数指针,那就是说,它能够引用函数。

那么,定义一个委托,也就等于定义一个函数指针,

那么,函数指针指向一些什么样的函数呢?

这就在定义委托的时候决定了,如:

public delegate void ShowDelegate(int p);

这就定义了一个委托 ShowDelegate。他指向的函数的返回类型为:void,函数有 1 个参数,类型为 int 型。

委托可以用来调用函数,如:

    ShowDelegate abc = new ShowDelegate(ShowHi);

    abc(15);

也可以做为函数的参数。

但大多数委托的用途多用于事件上。

事件就是委托的实例:

public event 委托名(xxxEventHandler) 事件名/实例名;

详细请看:

http://www.cnblogs.com/finesite/articles/255884.html


using System;

public class TestDelegate
{

    public delegate void ShowDelegate(int p);

    public static void ShowHi(int a)
    {
        Console.Write("Hi:{0}\n", a);
    }

    public static void ShowHello(int b)
    {
        Console.Write("Hello:{0}\n", b);
    }

    public static void HowShow(ShowDelegate pr)
    {
        int a = 10;
        pr(a);
    }

    public static void Main()
    {
        HowShow(new ShowDelegate(ShowHello));

        ShowDelegate abc = new ShowDelegate(ShowHi);

        abc(15);
    }

}

个人博客终于上线

  这也是博客!!还不如说是个留言板。(呵呵,慢慢来嘛,好的开始就是成功的一半嘛)

  表面看起来再普通不过了,但里面框架并不简单。学习 asp.net 不久,目前很多东西还是参考别人的代码,这个博客程序是参考 CNBlogsDottext10Beta2 和 CS_2.0.60217.2664 而写,现在只是单用户,等做成成熟的博客程序时,我会将它全部开源,并希望同 asp.net 爱好者共同探讨里面的技术。