设为首页 收藏本站
查看: 1762|回复: 0

[SharePoint 开发详解] 自定义字段开发 II: FTP上传字段

[复制链接]

尚未签到

发表于 2015-5-26 09:46:15 | 显示全部楼层 |阅读模式
  众所周知,在MOSS 2007 中,当我们为List中的某一个Item上传附件的时候,这个附件是以二进制的形式存放在数据库中的,当我们需要下载的时候,SharePoint Service再为我们还原成原来的附件。SharePoint 还为附件的大小做了限制,一般都在50M。那么如果有的用户想把一些大Size 的文件作为附件上传的时候,就会产生问题。而且大文件上传,下载均设计到数据库操作,对系统的性能要求会比较大。我们在曾经遇到过美国的同事上传附件到在中国的SharePoint server上,由于附件比较大,带宽有限,就产生过上传出错的问题。还有在MOSS2007中,附件没办法批量上传和下载到List的某个Item中,用户只要one by one的去下载附件,用户体验不够友好。
  综上需求,开发了一个自定义字段:FTP上传字段。功能如下:
  1.当用户在一个List下新建一个Item的时候,在用户设定的FTP server上自动创建一个文件夹。
  2.文件夹地址作为自定义字段的值显示,用户可以点击这个链接地址,进行批量的附件上传下载。
  下面介绍详细的开发过程:
  1.首先还是创建一个自定义字段的Project
  2.先添加一个FTP的操作的工具类,我们称为FTPClientUtility,完成一切在FTP server上的操作,如附件上传,创建文件夹,计算文件夹当前大小等等
  FTPClientUtility的主要方法如下:
  

DSC0000.gif DSC0001.gif 代码

  public bool UploadFile(string path, string fileName, string location)
        {
            StreamReader sourceStream = null;
            Stream requestStream = null;
            FtpWebResponse response = null;
            try
            {
                FtpWebRequest request = (FtpWebRequest)WebRequest.Create(this.FTPUrl + "/" + location + "/" + fileName);
                request.Method = WebRequestMethods.Ftp.UploadFile;
                request.UseBinary = true;
                request.Credentials = new NetworkCredential(this.UserName, this.Password);
               
                sourceStream = new StreamReader(path);
                byte[] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
                sourceStream.Close();
                request.ContentLength = fileContents.Length;
                requestStream = request.GetRequestStream();
                requestStream.Write(fileContents, 0, fileContents.Length);
                requestStream.Close();
                response = (FtpWebResponse)request.GetResponse();
               // string result = response.StatusDescription;
                response.Close();
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
            finally
            {
                if (null != sourceStream)
                {
                    sourceStream.Close();
                }
                if (null != requestStream)
                {
                    requestStream.Close();
                }
                if (null != response)
                {
                    response.Close();
                }
            }
        }
        public bool CreateFolder(string folderName)
        {
            FtpWebResponse response = null;
            try
            {
                FtpWebRequest request = (FtpWebRequest)WebRequest.Create(this.FTPUrl + "/" + folderName);
                request.Method = WebRequestMethods.Ftp.MakeDirectory;
                request.UseBinary = true;
                request.Credentials = new NetworkCredential(this.UserName, this.Password);
                response = (FtpWebResponse)request.GetResponse();
                response.Close();
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
            finally
            {
                if (null != response)
                {
                    response.Close();
                }
            }
        }
        public bool IsFolderOrFileExist(string folderName, string destinationFolderLocation)
        {
            FtpWebResponse response = null;
            StreamReader reader = null;
            IList fileList = new List();
            try
            {
                FtpWebRequest request = (FtpWebRequest)WebRequest.Create(this.FTPUrl + destinationFolderLocation);
                request.Method = WebRequestMethods.Ftp.ListDirectory;
                request.UseBinary = true;
                request.Credentials = new NetworkCredential(this.UserName, this.Password);
                response = (FtpWebResponse)request.GetResponse();
                reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
                string line = String.Empty;
                while(!String.IsNullOrEmpty(line = reader.ReadLine()))
                {
                    line = line.Split('_')[0];
                    fileList.Add(line);
                }
                response.Close();
                reader.Close();
                string folderId = folderName.Split('_')[0];
                return fileList.Contains(folderId);
            }
            catch (Exception ex)
            {
                return false;
            }
            finally
            {
                if (null != response)
                {
                    response.Close();
                }
                if (null != reader)
                {
                    reader.Close();
                }
            }
        }
        public List GetListDirectoryDetails(string destinationFolderLocation)
        {
            StreamReader reader = null;
            FtpWebResponse response = null;
            List fileList = new List();
            try
            {
                FtpWebRequest request = (FtpWebRequest)WebRequest.Create(this.FTPUrl + destinationFolderLocation);
                request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
                request.UseBinary = true;
                request.Credentials = new NetworkCredential(this.UserName, this.Password);
                response = (FtpWebResponse)request.GetResponse();
                reader = new StreamReader(response.GetResponseStream());
                string line = "";
                string fileName = "";
                string folderName = "";
                string[] info = null;
                IList filesInfo = new List();
                while (!String.IsNullOrEmpty(line = reader.ReadLine())) //Save the response stream in memory so the response can be closed and will not hanged in
                {
                    filesInfo.Add(line);
                }
                int startIndex = 0;
                System.Text.RegularExpressions.Regex rg = new System.Text.RegularExpressions.Regex(@"\d");
                foreach (string fileLine in filesInfo)
                {
                    if (fileLine.IndexOf("") == -1)
                    {
                        fileName = rg.Replace(fileLine.Substring(20), "").Trim();
                        fileList.Add(fileName);
                    }
                    else
                    {
                        startIndex = fileLine.IndexOf("");
                        folderName = fileLine.Substring(startIndex + 5, fileLine.Length - startIndex - 5).Trim();
                        fileList.Add(folderName);
                    }
                }
                response.Close();
                return fileList;
            }
            catch (Exception ex)
            {
                return null;
            }
        }
        public long GetFolderSize(string destinationFolderLocation)
        {
            long fileSize = 0;
            StreamReader reader = null;
            FtpWebResponse response = null;
            long totalFileSize = 0;
            try
            {
                FtpWebRequest request = (FtpWebRequest)WebRequest.Create(this.FTPUrl + destinationFolderLocation);
                request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
                request.UseBinary = true;
                request.Credentials = new NetworkCredential(this.UserName,this.Password);
                response = (FtpWebResponse)request.GetResponse();
                reader = new StreamReader(response.GetResponseStream());
                string line = "";
                string fileName = "";
                string folderName = "";
                string[] info = null;
                IList filesInfo = new List();
                while (!String.IsNullOrEmpty(line = reader.ReadLine())) //Save the response stream in memory so the response can be closed and will not hanged in
                {
                    filesInfo.Add(line);
                }
                int startIndex = 0;
                foreach (string fileLine in filesInfo)
                {
                    if (fileLine.IndexOf("") == -1)
                    {
                        info = fileLine.Split(' ');
                        fileName = info[info.Length - 1];
                        totalFileSize += Convert.ToInt64(info[info.Length - 2]);
                    }
                    else
                    {
                        startIndex = fileLine.IndexOf("");
                        folderName = fileLine.Substring(startIndex + 5, fileLine.Length - startIndex - 5).Trim();
                        response.Close();
                        totalFileSize += GetFolderSize(destinationFolderLocation + "/" + folderName);
                    }
                }
                return totalFileSize;
            }
            catch (Exception ex)
            {
                return 0;
            }
        }
        public long GetFileSize(string fileName, string destinationFolderLocation)
        {
            long fileSize = 0;
            FtpWebResponse response = null;
            try
            {
                FileInfo fileInf = new FileInfo(fileName);
                FtpWebRequest request = (FtpWebRequest)WebRequest.Create(this.FTPUrl + destinationFolderLocation + "/" + fileInf.Name);
                request.Method = WebRequestMethods.Ftp.GetFileSize;
                request.UseBinary = true;
                request.Credentials = new NetworkCredential(this.UserName, this.Password);
                response = (FtpWebResponse)request.GetResponse();
                fileSize = response.ContentLength;
                response.Close();
                return fileSize;
            }
            catch (Exception ex)
            {
                return 0;
            }
            finally
            {
                if (null != response)
                {
                    response.Close();
                }
            }
        }  
  3. 自定义字段的实现类,和普通的自定义字段实现类类似,没什么特别的,代码如下
  

代码

  public class FileUploadField : SPFieldText
    {
      
        public FileUploadField(SPFieldCollection fields, string fieldName)
            : base(fields, fieldName)
        {
            InitProperties();
        }
        public FileUploadField(SPFieldCollection fields, string typeName, string displayName)
            : base(fields, typeName, displayName)
        {
            InitProperties();
        }
        public override BaseFieldControl FieldRenderingControl
        {
            get
            {
                BaseFieldControl fieldControl = new FileUploadFieldControl(this);
                fieldControl.FieldName = InternalName;
                return fieldControl;
            }
        }
   }  
  4. 自定义字段的呈现类,当Item新建时,要完成在FTP上创建相应的文件夹的工作,当用户Edit/View时,将创建的文件夹地址作为此字段的值显示,主要代码:
  

代码

public class FileUploadFieldControl : BaseFieldControl
    {
        private FileUploadField field;
        private LinkButton updateLink;
        private HyperLink fileLink;
        private FTPClientUtility ftpUtility;
        private HtmlTable fileTable;
        long folderMaxSize;
        public FileUploadFieldControl(FileUploadField parentField)
        {
            this.field = parentField;
            this.updateLink = new LinkButton();
            this.fileLink = new HyperLink();
            this.ftpUtility = new FTPClientUtility();
            this.fileTable = new HtmlTable();
            Dictionary ftpInfo = GetFtpUrl();
            ftpUtility.FTPUrl = ftpInfo["Url"];
            ftpUtility.UserName = ftpInfo["UserName"];
            ftpUtility.Password = ftpInfo["Password"];
            folderMaxSize = Convert.ToInt64(ftpInfo["FolderSize"]);
        }
        private Dictionary GetFtpUrl()
        {
            string ftpFile = Environment.CurrentDirectory + "\\FtpInfo.xml";
            Dictionary ftpInfo = new Dictionary();
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(ftpFile);
            string ftpUrl = xmlDoc.DocumentElement.SelectSingleNode("//Url").InnerText;
            ftpInfo.Add("Url", ftpUrl);
            string userName = xmlDoc.DocumentElement.SelectSingleNode("//UserName").InnerText;
            ftpInfo.Add("UserName", userName);
            string password = xmlDoc.DocumentElement.SelectSingleNode("//Password").InnerText;
            ftpInfo.Add("Password", password);
            string folderSize = xmlDoc.DocumentElement.SelectSingleNode("//FolderSize").InnerText;
            ftpInfo.Add("FolderSize", folderSize);
            return ftpInfo;
        }
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
        }
        protected override void CreateChildControls()
        {
            base.CreateChildControls();
            try
            {
                if (null == this.updateLink)
                {
                    this.updateLink = new LinkButton();
                }
                string backUrl = String.Empty;
                string webUrl = SPContext.Current.Web.Url;
                string formUrl = String.Empty;
                if(this.ControlMode == SPControlMode.Edit || this.ControlMode == SPControlMode.Display)
                {
                    string webID = SPContext.Current.Web.ID.ToString();
                    string webName = SPContext.Current.Web.Title;
                    string webFolderName = webID + "_" + webName;
                    string listID = SPContext.Current.ListId.ToString();
                    string listName = SPContext.Current.List.Title;
                    string listFolderName = listID + "_" + listName;
                    string itemID = SPContext.Current.ItemId.ToString();
                    //if item fold has been created, this field layouted as a html link, else this field layouted as a link button
                    if (ftpUtility.IsFolderOrFileExist(webFolderName, ""))
                    {
                        //list folder has been created on FTP
                        if (ftpUtility.IsFolderOrFileExist(listFolderName, "/" + webFolderName))
                        {
                            //item folder has been created
                            if (ftpUtility.IsFolderOrFileExist(itemID, "/" + webFolderName + "/" + listFolderName))
                            {
                                long folderSize = ftpUtility.GetFolderSize("/" + webFolderName + "/" + listFolderName + "/" + itemID);
                                string js = String.Empty;
                                if (folderSize > this.folderMaxSize)
                                {
                                    js = "alert('This folder is full without any space, you cannot upload any file before you clean up it.');";
                                }
                                else
                                {
                                    js = "window.open('" + this.ftpUtility.FTPUrl + "/" + webFolderName + "/" + listFolderName + "/" + itemID + "','','height=500,width=700,toolbar=yes,status=no');";
                                }
                                this.fileLink.Attributes.Add("onclick", js);
                                js = "this.style.textDecoration = 'underline'; this.style.cursor='hand';";
                                this.fileLink.Attributes.Add("onmouseover", js);
                                this.fileLink.Attributes.Add("onmouseout", "this.style.textDecoration = 'none'");
                                this.fileLink.Text = "Attachment";
                                List fileList = ftpUtility.GetListDirectoryDetails("/" + webFolderName + "/" + listFolderName + "/" + itemID);
                                HtmlTableRow tableRow = null;
                                HtmlTableCell cell = null;
                                foreach(string file in fileList)
                                {
                                    tableRow = new HtmlTableRow();
                                    cell = new HtmlTableCell();
                                    cell.Attributes.Add("Class", "ms-vb");
                                    cell.InnerHtml ="" + file + "";
                                    tableRow.Cells.Add(cell);
                                    this.fileTable.Rows.Add(tableRow);
                                }
                                this.Controls.Clear();
                                this.Controls.Add(fileLink);
                                this.Controls.Add(this.fileTable);
                            }
                            else
                            {
                                this.updateLink.Click += new EventHandler(updateLink_Click);
                                this.updateLink.Text = "Attachment";
                                this.Controls.Clear();
                                this.Controls.Add(updateLink);
                            }
                        }
                        else
                        {
                            this.updateLink.Click += new EventHandler(updateLink_Click);
                            this.updateLink.Text = "Attachment";
                            this.Controls.Clear();
                            this.Controls.Add(updateLink);
                        }
                    }
                    else
                    {
                        this.updateLink.Click += new EventHandler(updateLink_Click);
                        this.updateLink.Text = "Attachment";
                        this.Controls.Clear();
                        this.Controls.Add(updateLink);
                    }
                }
                else if (this.ControlMode == SPControlMode.New)
                {
                    this.fileLink.Text = "Attachment(Please update and download files in edit page.)";
                    this.Controls.Clear();
                    this.Controls.Add(fileLink);
                }
            }
            catch (Exception)
            {
                ;
            }
        }
        protected void updateLink_Click(object sender, EventArgs e)
        {
            string webID = SPContext.Current.Web.ID.ToString();
            string webName = SPContext.Current.Web.Title;
            string webFolderName = webID + "_" + webName;
            string listID = SPContext.Current.ListId.ToString();
            string listName = SPContext.Current.List.Title;
            string listFolderName = listID + "_" + listName;
            string itemID = SPContext.Current.ItemId.ToString();
            try
            {
                if (ftpUtility.IsFolderOrFileExist(webFolderName, ""))
                {
                    if (ftpUtility.IsFolderOrFileExist(listFolderName, "/" + webFolderName))
                    {
                        if (ftpUtility.IsFolderOrFileExist(itemID, "/" + webFolderName + "/" + listFolderName))
                        {
                            return;
                        }
                        else
                        {
                            this.ftpUtility.CreateFolder(webFolderName + "/" + listFolderName + "/" + itemID);
                        }
                    }
                    else
                    {
                        this.ftpUtility.CreateFolder(webFolderName + "/" + listFolderName);
                        this.ftpUtility.CreateFolder(webFolderName + "/" + listFolderName + "/" + itemID);
                    }
                }
                else
                {
                    this.ftpUtility.CreateFolder(webFolderName);
                    this.ftpUtility.CreateFolder(webFolderName + "/" + listFolderName);
                    this.ftpUtility.CreateFolder(webFolderName + "/" + listFolderName + "/" + itemID);
                }
                //Context.Response.Redirect(this.ftpUtility.FTPUrl + "/" + webFolderName + "/" + listFolderName + "/" + itemID);
                string js = "window.open('" + this.ftpUtility.FTPUrl + "/" + webFolderName + "/" + listFolderName + "/" + itemID + "','','height=500,width=700,toolbar=yes,status=no') ";
                Context.Response.Write(js);
            }
            catch
            {
                return;
            }
        }
        protected override void Render(HtmlTextWriter output)
        {
            base.Render(output);
            if (this.ControlMode == SPControlMode.Display)
            {
                string webID = SPContext.Current.Web.ID.ToString();
                string webName = SPContext.Current.Web.Title;
                string webFolderName = webID + "_" + webName;
                string listID = SPContext.Current.ListId.ToString();
                string listName = SPContext.Current.List.Title;
                string listFolderName = listID + "_" + listName;
                string itemID = SPContext.Current.ItemId.ToString();
                if (ftpUtility.IsFolderOrFileExist(webFolderName, ""))
                {
                    //list folder has been created on FTP
                    if (ftpUtility.IsFolderOrFileExist(listFolderName, "/" + webFolderName))
                    {
                        //item folder has been created
                        if (ftpUtility.IsFolderOrFileExist(itemID, "/" + webFolderName + "/" + listFolderName))
                        {
                            string uploadFileHref = "Attachment";
                            output.Write(uploadFileHref);
                        }
                        else
                        {
                            output.Write("Please create file repository in edit page");
                        }
                    }
                }
            }
        }
        public override void UpdateFieldValueInItem()
        {
            this.EnsureChildControls();
            try
            {
                this.Value = this.updateLink.Text;
                this.ItemFieldValue = this.Value;
            }
            catch (Exception)
            {
                ;
            }
        }
        public override object Value
        {
            get
            {
                this.EnsureChildControls();
                if (this.updateLink != null)
                    return "";
                else
                    return null;
            }
        }
    }  
  可以在代码中发现,在FTP上创建的文件夹按照"WebID/ListID/ItemID"的层次结构创建。避免了文件夹的重复创建以及附件的分类问题。
  接下来可以创建一个.xml文件,将FTP server的地址,用户的ID和密码写入,当这些基础信息发生改变时,只要配置这个Xml文件即可而不需要修改代码。部署时将此XML文件放入 "系统目录\Windows\system32\inetsrv,以确保能够被我们的自定义字段程序访问。
  部署完此字段,为任何一个List添加自定义字段,下面是效果图:
  新建Item:
DSC0002.jpg
  编辑Item:
DSC0003.jpg
  点击Attachment链接,打开ftp目录,就可以上传下载属于此Item的附件了:
  
DSC0004.jpg
  
  
  安装文件可以在此下载:/Files/tonnie/AECSharePoint.Field.FileTransfer.rar
  欢迎指正!谢谢!
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-70790-1-1.html 上篇帖子: 使用FtpWebRequest 类操作(上传、下载和删除)FTP上的XML文件 下篇帖子: SQL Server 跨网段(跨机房)FTP复制
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表