天天看点

Asp.Net控件的客户端命名

我们在用asp.net写出来的网页,用浏览器来查看生成的客户端代码的时候经常看到这样的代码:gridview1_ctl101_webusercontrol1_webusercontrolbutton,那么这个命名有什么规律,是怎么来的拉?本次我们使用reflector查看.net的代码研究其中的规律。

我们的asp.net服务器端控件在生成客户端控件的时候一般有id 和name两个属性,这两个属性我们在服务器端可以通过clientid和uniqueid来得到。

以一个button为例,用reflector打开system.web.dll,找到system.web.ui.webcontrols命名空间下面的button类,我们可以发现该类继承至webcontrol类,其实大多数控件都继承至这个类。这个类是继承了system.web.ui.control类的,这个类是我们要研究的重点,该类继承至system.object类,这是所有类的基类,我们就不去研究了,接下来我们来看看control类。

找到control类下面的clientid属性,查看其代码如下:

Asp.Net控件的客户端命名

public virtual string clientid

Asp.Net控件的客户端命名

{

Asp.Net控件的客户端命名

    get

Asp.Net控件的客户端命名

    {

Asp.Net控件的客户端命名

        this.ensureid();

Asp.Net控件的客户端命名

        string uniqueid = this.uniqueid;

Asp.Net控件的客户端命名

        if ((uniqueid != null) && (uniqueid.indexof(this.idseparator) >= 0))

Asp.Net控件的客户端命名

        {

Asp.Net控件的客户端命名

            return uniqueid.replace(this.idseparator, '_');

Asp.Net控件的客户端命名

        }

Asp.Net控件的客户端命名

        return uniqueid;

Asp.Net控件的客户端命名

    }

Asp.Net控件的客户端命名

}

也就是说clientid就是将uniqueid中的idseparator (其值为:”$”)替换为”_”。比如我们写一个页面生成出来的代码如下:

<input type="submit" name="gridview1$ctl101$webusercontrol1$webusercontrolbutton" value="button" id="gridview1_ctl101_webusercontrol1_webusercontrolbutton" />

显然name和id的不同就是将其中$替换为了_。

现在clientid我们已经清楚了,那么uniqueid又是怎么生成的拉?让我们用reflector来看看。

Asp.Net控件的客户端命名

public virtual string uniqueid

Asp.Net控件的客户端命名
Asp.Net控件的客户端命名
Asp.Net控件的客户端命名
Asp.Net控件的客户端命名

        if (this._cacheduniqueid == null)

Asp.Net控件的客户端命名
Asp.Net控件的客户端命名

            control namingcontainer = this.namingcontainer;//获得父控件

Asp.Net控件的客户端命名

            if (namingcontainer == null)

Asp.Net控件的客户端命名

            {

Asp.Net控件的客户端命名

                return this._id;

Asp.Net控件的客户端命名

            }

Asp.Net控件的客户端命名

            if (this._id == null)

Asp.Net控件的客户端命名
Asp.Net控件的客户端命名

                this.generateautomaticid();//对控件自动编号

Asp.Net控件的客户端命名
Asp.Net控件的客户端命名

            if (this.page == namingcontainer)//当前控件的父控件是page则uniqueid就是控件的id。

Asp.Net控件的客户端命名
Asp.Net控件的客户端命名

                this._cacheduniqueid = this._id;

Asp.Net控件的客户端命名
Asp.Net控件的客户端命名

            else//当前控件父控件是另一种容器控件

Asp.Net控件的客户端命名
Asp.Net控件的客户端命名

                string uniqueidprefix = namingcontainer.getuniqueidprefix();//取得父控件uniqueid+分隔符($)作为当前控件的uniqueid前缀。

Asp.Net控件的客户端命名

                if (uniqueidprefix.length == 0)

Asp.Net控件的客户端命名

                {

Asp.Net控件的客户端命名

                    return this._id;

Asp.Net控件的客户端命名

                }

Asp.Net控件的客户端命名

                this._cacheduniqueid = uniqueidprefix + this._id;//前缀+id 作为当前控件的uniqueid

Asp.Net控件的客户端命名
Asp.Net控件的客户端命名
Asp.Net控件的客户端命名

        return this._cacheduniqueid;

Asp.Net控件的客户端命名
Asp.Net控件的客户端命名
Asp.Net控件的客户端命名

这段代码中,最重要的就是generateautomaticid()函数和namingcontainer.getuniqueidprefix();函数。我们可以跟进去看看函数是如何实现的。

Asp.Net控件的客户端命名

private void generateautomaticid()

Asp.Net控件的客户端命名
Asp.Net控件的客户端命名

    this.flags.set(0x200000);

Asp.Net控件的客户端命名

    this._namingcontainer.ensureoccasionalfields();

Asp.Net控件的客户端命名

    int index = this._namingcontainer._occasionalfields.namedcontrolsid++;

Asp.Net控件的客户端命名

    if (this.enablelegacyrendering)

Asp.Net控件的客户端命名
Asp.Net控件的客户端命名

        this._id = "_ctl" + index.tostring(numberformatinfo.invariantinfo);

Asp.Net控件的客户端命名
Asp.Net控件的客户端命名

    else if (index < 0x80)

Asp.Net控件的客户端命名
Asp.Net控件的客户端命名

        this._id = automaticids[index];

Asp.Net控件的客户端命名
Asp.Net控件的客户端命名

    else

Asp.Net控件的客户端命名
Asp.Net控件的客户端命名

        this._id = "ctl" + index.tostring(numberformatinfo.invariantinfo);

Asp.Net控件的客户端命名
Asp.Net控件的客户端命名

    this._namingcontainer.dirtynametable();

Asp.Net控件的客户端命名
Asp.Net控件的客户端命名

从这个函数我们可以看出,对于像gridview这种绑定控件,其生成的每一行中的控件名是由ctl+自增的数字组成的。其中数字的格式化是两位数字,也就是说不足两位的时候补零,多出两位就按实际内容算。

Asp.Net控件的客户端命名

internal virtual string getuniqueidprefix()

Asp.Net控件的客户端命名
Asp.Net控件的客户端命名

    this.ensureoccasionalfields();

Asp.Net控件的客户端命名

    if (this._occasionalfields.uniqueidprefix == null)

Asp.Net控件的客户端命名
Asp.Net控件的客户端命名
Asp.Net控件的客户端命名

        if (!string.isnullorempty(uniqueid))

Asp.Net控件的客户端命名
Asp.Net控件的客户端命名

            this._occasionalfields.uniqueidprefix = uniqueid + this.idseparator;

Asp.Net控件的客户端命名
Asp.Net控件的客户端命名

        else

Asp.Net控件的客户端命名
Asp.Net控件的客户端命名

            this._occasionalfields.uniqueidprefix = string.empty;

Asp.Net控件的客户端命名
Asp.Net控件的客户端命名
Asp.Net控件的客户端命名

    return this._occasionalfields.uniqueidprefix;

Asp.Net控件的客户端命名
Asp.Net控件的客户端命名

这个函数返回父控件的uniqueid+idseparator,如果父控件uniqueid为空,那么就返回空。

现在我们再回过头来看看gridview1$ctl101$webusercontrol1$webusercontrolbutton这命名:从中我们可以看到这是一个gridview控件下面绑定了一个webusercontrol控件,而这个控件中有一个webusercontrolbutton控件。

继续阅读