SharePoint 2013 開發文檔管理字段小記


前言

  最近有這樣一個需求,就是要求在列表庫里管理文檔,需要多文檔管理、帶版本控制、可以單獨授權等基本操作。於是乎,就開發了一個自定義段,這里介紹一下字段的思路,里面有一些遇到的問題,在群友的幫助下已解決,特此感謝群友[悉尼]Jay,大胡子帥哥。

思路

  首先簡單說一下自定義字段的思路,既然要管理文檔,就需要用到文檔庫,所以在解決方案里帶上一個文檔庫,開啟版本控制(文檔庫的xml里有這個屬性 VersioningEnabled="true");

  其次,創建字段,繼承自SPFieldMultiLineText,一開始想要把很多東西保存進來,選擇了繼承自多行文本類型,后來只存了關聯使用的字段的一個Guid值,所以想想單行文本或許更佳。如果你未曾創建過自定義字段,可以參考我博客置頂的開發系列,里面有字段開發圖文教程;

  再次,創建BaseFieldControl類,同時創建前台展示控件,也就是ascx控件,里面有顯示模板、編輯模板、JavaScript和Ajax等;

  然后,創建應用程序頁面,用來上傳和刪除文檔,也就是管理文檔,里面用到了SPGridView控件,然后里面還有版本控制頁面,因為自己犯懶,所以版本控制用了SharePoint自帶的Version.aspx頁面,后來也遇到了一些問題;

  最后,以上基本上是大致思路,可能這樣貿然看起來比較糾結,下面讓我們用圖片形象化一下下,Let’s Go!

圖解

  其間部署,激活網站Feature等略過,我們只描述相對重要的部分;在我們的列表里添加字段(因為我們開發的就是字段么),選擇部署好的字段,如果部署成功但是沒有,試着重啟一下IIS,或者回收應用程序池,如下圖:

clip_image002

  然后,點擊新建項目,我們的字段已經創建成功,點擊Edit Attachments可以進入管理頁面,當然這個詞還是我隨便起的,因為我也沒想好叫什么,等着Manger們提意見了,如下圖:

clip_image004

  進入管理頁面,這里用的是SharePoint自己的模態窗口,當然寬度和長度是我自己猜想的,汗!里面的頁面就是我定義的應用程序頁,也就是上傳控件+SPGridView控件展示,用了模態窗口的dialogReturnValueCallback屬性,在關閉模態窗口的時候,刷新編輯頁面的值顯示;

clip_image006

  上傳功能就很簡單了,就是上傳控件+Button,沒什么可說的,后台服務器端對象模型,OverWrite上傳,然后重名會產生版本;下面是顯示的圖,我上傳了幾個文檔,如下圖:

  這里面也沒有什么復雜的東西,就是下載(Link的文檔的鏈接),刪除(delete執行一個JavaScript方法,傳進去該項目的ID,然后js Call一個后台方法,根據這個Id刪除,然后刷新),版本控制(Link到版本控制頁面,另一個根據SharePoint自帶version.aspx改造的);

clip_image008

  其實關於Delete自己想說一點,不知道自己用的方法是不是很好,就是在SPGridView生產html的時候,格式化成腳本,如下圖:

clip_image010

  然后用腳本去Call后台方法把這個Id=16的項目delete掉,如果大家有更好的方法,期待留言給我!

  然后是版本控制頁面,前面也已經說了,這里是根據SharePoint自帶的/_layouts/15/version.aspx改造的,然后隱藏了左側導航、Ribbon等不想干的東西,拼成Link顯示的,如下圖:

clip_image012

  說說link的大致結構,也是參考version.aspx拼的,首先就是頁面地址,然后list的guid,然后是這個項目的ID,然后是這個文件的文件名,最后是我定義的返回鏈接,也就是上面Go back Attachment Lists按鈕返回的地址;

1 /_layouts/15/SharePoint.AttachmentWithVersion/Versions.aspx?
2 list={9d0234b8-23c4-4f4f-bc5a-f21908aaba79}&
3 ID=16&
4 FileName=1.png&
5 SourceUrl=/sites/JianYu/SubDemo/_layouts/15/PwC.SharePoint.AttachmentWithVersion/UpLoadPwCAttachments.aspx?AttachmentsId=8638db30-133f-489e-8139-4abd36b0785f

  着重說一下這個頁面的改造,我想對於SharePoint后續開發還是有幫助的,其實自己也是因為偷懶給自己挖了一個坑;不貧了,進入正題!

  其實這個頁面很好用,改了改樣式,隱藏掉一些不需要的東西,加一個返回按鈕,已經成型了;就在自己興高采烈的時候,發現了問題,所有功能都沒問題,正常運行,但是發現Delete All Versions、Restore、Delete幾個功能,執行完畢以后,返回默認的version.aspx頁面,而不是我這個自定義的頁面,這下慌了;

  自己首先想到JavaScript的問題,然后根據F12Debug發現了core.js的問題,然后custom一個core.js給這個頁面引用,進行修改(千萬不要改默認,有可能印象默認功能,也有可能打補丁被覆蓋!),自己研究了半天core.js無解,然后就是大胡子帥哥Jay發了我一個Link,然后恍然大悟;

  執行過程是這樣的,通過core.js里面的腳本,然后傳參去call 默認的version.aspx,然后進行后台處理后展示,大致思路是這樣的,后台自己反編譯了Microsoft.SharePoint.ApplicationPages.VersionsPage文件,發現確實是傳參和后台處理有問題,然后找到了解決辦法!

  找到Restore的腳本,在core.js(默認layouts下面)中,我使用了格式化工具,格式化成正常格式,如下圖:

  經過分析發現就是SubmitFormPost(b)中參數b的問題,默認是下面格式,提交到versions.aspx進行處理,然后展示,所以一定會回到默認頁面展示了,所以我首先替換了這個地址為自己定義version.aspx的地址;

  /_layouts/15/versions.aspx?FileName=banner%2Ejpg&list={4059c14d-b1ee-4216-828d-429ef5271d52}&ID=10&col=Number&order=d&op=Restore&ver=512

clip_image014

  然后發現,所有問題,都是由內部方法public string SortUrl(string col, string order)引起的,它在處理完所有請求以后,跳轉到了一個地址,這個地址是根據默認Layouts目錄產生的,汗!

clip_image016

  然后我在后台找到了Restore方法,發現是在最后一行this.RefreshWithoutOp();中跳轉的;

clip_image018

  RefreshWithoutOp()方法,就這樣結合core.js和反編譯工具,整理清楚了運行的整個過程,然后就是解決問題了,到這里,其實已經折騰快2天了,糾結啊!

clip_image020

  研究通過程以后,又反過來看core.js,發現了前台js如何去call這個方法,也就是之前說的參數b的問題了,下面一行就是我修改以后的參數b,替換了處理頁面(a.HttpPath),op就是傳參進來的后台方法,itemTable.getAttribute是當前項目的信息;

  var b = a.HttpPath.replace("_layouts/15/versions.aspx", "_layouts/15/SharePoint.AttachmentWithVersion/versions.aspx") + "&op=CustomRestore&ver=" + itemTable.getAttribute("verId");

  至此,找到了解決思路,也就是吧op傳進來的方法Restore改成CustomRestore,在我自定義的version.aspx頁面的前台重新定義CustomRestore方法;

clip_image022

  修改調用的this.RefreshWithoutOp();為this.CustomRefreshWithoutOp();然后在前台添加CustomRefreshWithoutOp方法;然后依次定義public string SortUrl()和public string SortUrl(string col, string order)方法,修改builder.Append("SharePoint.AttachmentWithVersion/versions.aspx");這樣,完成后就會跳轉到我們自定義的version.aspx頁面了,艾瑪,終於完成了!

clip_image024

  再有就是關閉這個管理頁面的時候,如何同步新建頁面/修改頁面的字段值的問題,這里,我用了關閉事件,去Call一段Ajax更新這個值,感覺很笨,但是也是沒辦法的事兒,哎!

  后來又遇到問題,在自定義母版頁中,關閉的時候Call事件不好用,不知道為什么,也沒有任何debug error,所以又在編輯控件上加了每隔3s刷新,如果call失敗了,就每隔3sCall一次,現在還不太清楚是否對於性能有太大影響,哎~

clip_image026

  以上基本上是開發思路和展示,還有遇到的一些問題,當然思路有點凌亂,確實是,開發過程雖然自己有一個小小的設計,但是依舊感覺凌亂;好吧,后期還待優化,下面看看Dispform頁和Allitems頁的展示吧!

  Allitems頁面的展示,public override string GetFieldValueAsHtml(object value)字段里的這個方法做的展示,沒什么特別要說的,呵呵;

clip_image028

  Dispform頁的展示,如下圖:

clip_image030

  下面,介紹一下解決方案的文件結構,如下圖:

clip_image032

總結

  一個最近開發的字段,把過程和遇到的問題記錄下來,算是一個小積累吧;里面碰到很多不常見但是很有用的東西,也希望能給有需要的人有些參考,呵呵!加油吧~~SharePoint~~

  其實自己寫完這篇博客,回看起來感覺比較凌亂,本來做起來也是很凌亂,后面有待於完善的功能也有很多,比如權限控制還是需要去文檔頁面管理,呵呵,先這樣,后面的事兒,繼續吧。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM