天天看點

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控件。

繼續閱讀