電腦正在以無比慢的速度從微軟網站上安裝Office Component for Visual Studio 2012,今晚的某個工作看來是干不成了,索性寫篇blog。
SharePoint是一個B/S結構的產品,所以在開發過程中會使用到各種各樣的上下文(Context)信息,借此機會來總結一下。
一、HttpContext
這個……我想就不用再介紹了,SharePoint運行在標准的ASP.NET框架下(2003用的不是標准的ASP.NET 1.1,不過這年頭還有人用2003么),所以這個對象的使用和ASP.NET沒有任何區別。
二、SPContext
從名字就可以看出來,這個是SharePoint自己的上下文對象,它除了封裝了HttpContext之外,提供了很多和SharePoint相關的上下文信息。
SPContext包含一個我們最經常使用的靜態屬性:SPContext.Current,用於獲取當前的上下文信息(和HttpContext.Current類似,如果程序是運行在Web上的,就可以使用這個)。我見過不少初學SharePoint開發的人,在寫WebPart的時候,還在使用new SPSite的方式來獲取當前網站集,這即沒有必要,也是對服務器資源的浪費(SPSite、SPWeb對象都包含非托管資源,而Current中的Site和Web是被SharePoint自己的運行時環境所管理的,可以快速取用)。
下面看一下這個SPContext中包含哪些常用的屬性,可以在開發過程中使用(有些屬性其實內部邏輯很復雜,這里簡要介紹一些基本場景):
屬性 | 說明 |
Site | SPSite類型,次常用到的屬性,當前的網站集 |
Web | SPWeb類型,最常用到的屬性,當前的網站。 很多程序都是用SPContext.Current.Web來開頭的…… |
List / ListId | SPList / Guid類型,當前列表。 不論你是在列表的視圖頁面上、表單頁面上還是設置頁面上,都可以通過這個屬性取得當前的列表。其實只要Url查詢里面有一個有效的List參數,參數的值是列表的Guid就可以。 |
ListItem / ItemId | SPListItem / Int32類型,當前的列表條目。 一般用於列表的查看和編輯表單(當然新建表單其實也可以,只不過沒有ID),或者用於獲取存放在頁面庫里的當前頁面對應的條目。此外,如果當前的List屬性有效的話,只要Url查詢里面有一個有效的ID參數,就可以使用這個屬性得到對應條目。 |
ListItemVersion | SPListItemVersion類型,當前列表條目對應的版本。 如果是從歷史版本查看頁面中,查看某個版本的條目時,在那個查看頁面,可以用這個屬性直接取到相應的版本。 |
ListItemDisplayName / ListItemServerRelativeUrl |
string / string類型,當前條目的顯示名稱(如果是普通列表,就是Title字段的值;如果是文檔庫,就是不帶擴展名的文件名;或者是文件夾名稱),以及Url。 |
File | SPFile類型,如果當前條目是一個文件的話,這個屬性可以直接得到文件對象。 相當於SPContext.Current.ListItem.File |
RootFolderUrl | string類型,當前視圖對應的Url地址。 如果當前列表視圖是處於列表的某個子文件夾中,可以通過這個屬性得到這個文件夾的地址;否則的話,就是當前列表的根文件夾地址。 |
IsPopUI | Boolean類型,判斷當前頁面是否在對話框中。 僅限SharePoint 2010那種對話框,不包括瀏覽器的那種模態對話框。 |
FormContext | SPFormContext類型,當前列表表單上下文(用於列表表單頁面) 一般可以使用這么幾個屬性: FormMode:表單類型,New / Edit / Display FieldControlCollection:表單上字段控件的集合 |
ViewContext | SPViewContext類型,當前視圖上下文(用於列表視圖頁面) 一般可以使用這么幾個屬性: View:SPView對象,當前的視圖 ViewId:視圖的Guid |
ContextPageInfo | SPContextPageInfo類型,當前頁面上下文(用於頁面庫中的頁面) 一般可以使用這么幾個屬性: ListId:頁面所在文檔庫的Id ItemId:當前頁面作為列表條目的Id BasePermissions:當前用戶對當前頁面的權限 IsWebWelcomePage:當前頁面是否是網站的首頁 |
三、JavaScript中的“ctx”
這個在微軟的SDK里面是沒有提及到的,在所有包含列表視圖的Web部件頁上,每個列表視圖都會對應一個ctx[blabla]的JavaScript變量,后面那個[blabla]是一個數字,這個數字也是這個變量的ctxId屬性。這些ctx變量都放在一個全局JavaScript變量g_ctxDict這個對象中,其key就是變量名字符串,value就是這個變量,因此便利這個全局變量,就能通過JavaScript找到當前頁面中的所有視圖。
ctx變量名義上是一個叫ContextInfo的JavaScript“類”,它包含非常豐富的屬性,常用的一些如下:
屬性 | 說明 |
ctxId | 一個標識此變量的數字,比如185,那么這個變量就是ctx185。使用的時候可以用ctx185或者g_ctxDict[‘ctx185’]來找到這個變量(某些情況下有種更簡便的方法,后面再說)。需要注意的是,每次刷新頁面的時候,這個標識可能是會變的,具體原理我暫時木有去深究。 |
listBaseType | 列表的基礎類型,相當於SPList的BaseType屬性 |
listTemplate | 列表的模版Id(比如文檔庫是101、通知是104),相當於SPList的BaseTemplate屬性 |
listName | 列表的Id,不要被變量名混淆了 |
view | 列表視圖的Id |
listUrlDir | 列表的根路徑,相當於spList.RootFolder.ServerRelativeUrl |
HttpRoot | 當前網站的根路徑(絕對路徑) |
SiteTitle | 當前網站的標題 |
ListTitle | 列表的標題(這個才是標題,listName不是) |
CurrentUserId | 當前用戶的Id |
wpq[*] | 渲染視圖那個WebPart的ID,比如WPQ2 |
ListData[*] | 這個就厲害了,這個屬性指向一個數組,而這個數組就是當前視圖顯示的那些列表條目,包含各個字段的值,JSON格式。 |
ListSchema[*] | 列表各個字段的定義(包含字段名稱、字段類型等等),JSON格式。 |
BasePermissions[*] | 當前用戶對這個列表的基本權限,形如下面這種樣子: {ManageLists: true, ManagePersonalViews: true, OpenItems: true} |
后面加[*]的那幾個是SharePoint 2013新增的屬性。
其實在包含列表視圖的頁面中,還有一個名字就叫“ctx”的變量,它指向這個頁面中最后一個ctx[blabla]變量,因此如果頁面中只有一個列表視圖的話,就可以直接使用ctx。比如在某個列表視圖頁面中,你想看一下這個列表模版的Id是多少,就可以直接在瀏覽器地址欄里輸入:javascript:alert(ctx.listTemplate) ,嗯。
ctx變量最主要的作用,就是生成列表項的那個下拉菜單(ECB – Edit Control Block),如果你去翻那個corev4.js的話,就可以看到在創建那個下拉菜單的時候,ctx是作為參數傳進去的。如果需要自定義列表項菜單的話,除了使用Feature的方式、或者2010新增的那個通過SPD添加Custom Action的方式,還可以使用從2007時代延續下來的JavaScript方式:在頁面中添加Custom_AddListMenuItems方法或者Custom_AddDocLibMenuItems方法(具體使用請自行搜索),而ctx就是這兩個方法的參數之一。
除此之外,作為列表視圖中重要的JavaScript變量,通過在頁面中嵌入的一些腳本中使用ctx,還可以完成各種比較邪惡的事情,請大家自行發揮想象。
四、JavaScript中的_spPageContextInfo變量
同樣是一個沒有文檔的JavaScript變量,雖然名字和前面提到的某個服務器端類型差不多,但是這個JavaScript變量里面所包含的內容,要比SPContextPageInfo多很多,它包含如下一些常用屬性:
屬性 | 說明 |
webServerRelativeUrl | 網站的相對服務器路徑(“/”開頭) |
currentLanguage | 當前網站的語言LCID |
webUIVersion | 當前網站的UI風格(2010/2013風格是4,如果母板頁是2007風格是3) |
pageListId | 頁面庫的列表Id |
pageItemId | 如果當前頁面是在頁面庫中的話,當前頁面作為列表條目的Id |
webAbsoluteUrl[*] | 網站絕對路徑(“http://”或者“https://”開頭) |
siteAbsoluteUrl[*] | 網站集絕對路徑(“http://”或者“https://”開頭) |
layoutsUrl[*] | layouts的相對服務器路徑(2013其實有兩個layouts root路徑,一個是15,一個是14) |
webTitle[*] | 網站標題 |
webPermMasks[*] | 當前用戶對當前網站的權限,形如:{High:2147483647,Low:4294967295} (因為JavaScript不支持64位整數,所以把高位和地位拆開了) |
siteServerRelativeUrl[*] | 網站集的相對服務器路徑(“/”開頭) |
后面加[*]的那幾個是SharePoint 2013新增的屬性。
_spPageContextInfo變量主要的使用場景,就是在JavaScript中獲取當前頁面的一些基本信息,尤其在發布頁面中,會有比較多的使用價值。
五、其他JavaScript全局變量
頁面中其實還有一些全局的JavaScript變量,也可以獲取到當前的一些上下文信息:
變量 | 說明 |
g_wsaLCID | 當前的語言,相當於_spPageContextInfo.currentLanguage |
g_wsaSiteTemplateId | 當前網站所使用的站點模版,比如“STS#1”表示工作組網站 |
_spUserId | 當前用戶的Id,這個JavaScript變量其實是右上角那個歡迎菜單渲染出來的 |
_spWebPermMasks | 當前用戶對當前網站的權限,相當於_spPageContextInfo.webPermMasks |