RSS

文档库下载副本,文件名被截断

九月 30

今天在TechNet上看到一个人问的问题(应该很早就有人发现这个问题了,2007应该就是这个样子),所以我估计我这个Blog里面写的也是很old的结论了。

原帖如下:sharepoint2010 从文档库下载文档副本 文件名被截断的问题

概括起来就是,当从文档库中下载副本的时候,过长的文件名被截断了(但是扩展名被保留);之前也有人发现过通过某些版本的浏览器文件另存为的时候也会这样。

这个原因是这样的:

下载副本是通过 /_layouts/download.aspx?SourceUrl=xxxx (xxxx就是你那个文件的路径)页面实现的,后台的类是Microsoft.SharePoint.ApplicationPages.Download,里面代码不多,不过篇幅所限就不全贴了,文件名是通过HttpHeader实现的,里面的核心方法AddContentDispostionHeader如下:

   1: private void AddContentDispositionHeader(string fileName)
   2: {
   3:     if ((this.Web != null) && (this.Web.Site.WebApplication.BrowserFileHandling == SPBrowserFileHandling.Strict))
   4:     {
   5:         base.Response.AppendHeader("X-Content-Type-Options", "nosniff");
   6:         base.Response.AppendHeader("X-Download-Options", "noopen");
   7:     }
   8:     base.Response.AppendHeader("Content-Disposition", "attachment;filename=\"" + SPHttpUtility.UrlEncodeFilenameForHttpHeader(fileName) + "\"");
   9: }
  10:  

可以看到,其中核心调用的方法是 SPHttpUtility.UrlEncodeFilenameForHttpHeader(str)

这个方法的实现如下:

   1: public static string UrlEncodeFilenameForHttpHeader(string fileName)
   2: {
   3:     string str = UrlEncodeForFilename(Path.GetExtension(fileName), 0x80, true);
   4:     string str2 = string.Empty;
   5:     if (str.Length < 0x80)
   6:     {
   7:         str2 = UrlEncodeForFilename(Path.GetFileNameWithoutExtension(fileName), 0x80 - str.Length, true);
   8:     }
   9:     return (str2 + str);
  10: }

我们可以看到,SharePoint把编码后文件名的总长度限制为128个字符,如果可能的话保留扩展名部分,截断超长的文件名。而Encode之后的中文类似于“%E4%B8%AD”这个样子(在UTF-8下,一个汉字用三个字节表示,前面那个表示“中”这个汉字),可以看到,一个汉字占了9个字符,因此就不难得到,如果扩展名是"“.docx”的话,那么前面的文件名长度最多只能容纳 (128 – 5) / 9 = 13.67,也就是13个汉字。

btw,实际上,在RFC中(参见:The Content-Disposition Header Field)中,规定了参数的长度不得超过78个字符,而且必须是编码的。当然,RFC只是个参考标准,每家都有自己的选择……

 

Posted by on 2011 年 09 月 30 日 in SharePoint

Leave a comment

发表评论