SharePoint 提供自訂清單欄位名稱,這些名稱會被轉成一種特別格式避開英數字以外的字元,例如「申請人」會被轉成「_x7533__x8acb__x4eba_」,術語叫 內部名稱 / Internal Name 而在撰寫 Sharepoint 程式時常需要用到內部名稱,例如 CAML 指定查詢條件時,FieldRef Name 就要傳入內部名稱:

<View>
<Query>
    <Where>
        <Eq>
            <FieldRef Name="_x7533__x8acb__x4eba_" />
            <Value Type="Text">Jeffrey</Value>
        </Eq>
    </Where>
</Query>
</View>

另外 ListItem.FieldValues 的 Key/Value,Key 也是用內部名稱,故你要取得特定清單欄位的值,必須先知道內部名稱是啥。

問題來了,一般我們在 SharePoint 網頁介面看到的都是顯示名稱,不會看到它對映的內部名稱,微軟文件提供了方法, 教你可以開瀏覽器試改欄位名稱,由 URL 觀察它轉換成的內部名稱。

還說 You can easily find out the internal name by editing an existing column and viewing the last parameter for the URL.,我覺得一點都不 Easy 啊!

大家知道我乃資訊王藍田,性急如火,叫我一筆一筆人工查詢轉換不如殺了我。想想轉換邏輯還算單純,自己寫個轉換函式應該不難,或許有些特殊規則沒涵蓋到,但能滿足 95% 就很好用了,遇到特例再調整修正,絕對勝過每次手工查。

用 Regex、Encoding 跟 LINQ 簡單幾行搞定,未來要寫 SharePoint 程式就不用花時間去查內部名稱囉。(註:內部名稱會在建立欄位時以顯示名稱轉換產生,事後修改顯示名稱不會跟著更新,這種情況只能透過查詢取得)

void Main()
{
	Console.WriteLine(ToSPInternalName("申請日期"));
	Console.WriteLine(FromSPInternalName("_x7533__x8acb__x65e5__x671f_"));
	Console.WriteLine(ToSPInternalName("VIP 註記"));
	Console.WriteLine(ToSPInternalName("註[*1]"));

}
static char[] keepChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".ToArray();
static string ToSPInternalName(string s) =>
    string.Join("", s.ToArray()
        .Select(c =>
        {
            if (keepChars.Contains(c)) return c.ToString();
            var b = Encoding.Unicode.GetBytes(c.ToString());
            return $"_x{b[1]:x2}{b[0]:x2}_";
        }).ToArray());
static string FromSPInternalName(string s) =>
    Regex.Replace(s, "_x(?<n>[0-9A-Fa-f]{4})_", m =>
    {
        var n = m.Groups["n"].Value;
        var b = new byte[2]
        {
            Convert.ToByte(n.Substring(2, 2), 16),
            Convert.ToByte(n.Substring(0, 2), 16)
        };
        return Encoding.Unicode.GetString(b);
    });

Writing a function to provider Sharepoint internal name conversion.


Comments

Be the first to post a comment

Post a comment