代码之家  ›  专栏  ›  技术社区  ›  B. Clay Shannon-B. Crow Raven

为什么选择Sharepoint文件。Add()导致I/O错误?

  •  0
  • B. Clay Shannon-B. Crow Raven  · 技术社区  · 11 年前

    使用此代码:

        using (var ms = new MemoryStream())
        {
            using (var doc = new Document(PageSize.A4, 25, 25, 10, 10)) 
            {
                //Create a writer that's bound to our PDF abstraction and our 
    stream
                using (var writer = PdfWriter.GetInstance(doc, ms))
                {
    
                    //Open the document for writing
                    doc.Open();
    
                    . . .
    
                }
            // File has been generated, now save it
            try
            {
                var bytes = ms.ToArray();
                String pdfFileID = GetYYYYMMDDAndUserNameAndAmount();
                String pdfFileName = String.Format("DirectPayDynamic_{0}.pdf", 
    pdfFileID);
                String fileFullpath = 
    Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirector
    y), pdfFileName); 
                String fileLinkBase = "Generated PDF: <a href=\"{0}\">{1}</a>";
                String filelink = String.Format(fileLinkBase, fileFullpath, 
    pdfFileName);
    
                File.WriteAllBytes(fileFullpath, bytes);
                AddVerticalSpace();                    
    
                var pdflink = new Label
                {
                    CssClass = "finaff-webform-field-label",
                    Text = filelink
                };
                this.Controls.Add(pdflink); 
    
        // NOTE: This is the new (non-working, exception-throwing) part of the 
    code, where we're trying to save the PDF file to a Sharepoint Document Library
                string destination = String.Format("DirectPayPDFForms/{0}", 
    pdfFileName); 
                SPSite siteCollection = new SPSite(siteUrl);
                SPWeb site = SPContext.Current.Web; 
                site.Files.Add(destination, ms); // this is the line that fails
        // end of new code      
            }
            catch (DocumentException dex)
            {
                exMsg = dex.Message;
            }
            catch (IOException ioex)
            {
                exMsg = ioex.Message;
            }
            catch (Exception ex)
            {
                exMsg = ex.Message;
                ; // for debugging: What is "ex" here?
            }
        } // using (var ms = new MemoryStream())            
    } // GeneratePDF
    

    ……我明白了,” 发生I/O错误 “(在IOException捕获块中)。这是一行:

    site.Files.Add(destination, ms);
    

    …引发错误。是我的目的地还是内存流导致了问题?“destination”是Sharepoint文档库(DirectPayPDFForms)的名称加上文件的生成名称。如果没有这段新代码,该方法运行良好,并将PDF文件放在服务器上(但这不是我们想要的地方-我们需要它首先转到文档库)。

    更新

    我得到了相同的异常,用调用this替换上面有问题的代码块:

    private void SavePDFToDocumentLibrary(MemoryStream memstrm)
    {
        string doclib = "DirectPayPDFForms";
        try
        {
            using (SPSite site = new SPSite(siteUrl))
            {
                using (SPWeb web = site.RootWeb)
                {
                    SPList list = web.Lists[doclib];
                    SPListItem spli = list.Items.Add();
                    spli["Title"] = String.Format("DirectPayPDFForms-{0}-{1}", GetUserId(), GetListTitleTimeStamp());
    
                    if (null != memstrm)
                    {
                        web.Files.Add(doclib, memstrm); 
                    }
                    // If this works, update at least some of the fields, such as Created, CreatedBy, etc.
                    spli.Update();
                }
            }
        }
        catch (Exception ex)
        {
            String s = String.Format("Exception is {0}", ex.Message);
        }
    }
    

    这种类型的代码在另一个实例中工作(我可以通过这种方式成功地将值保存到列表中),因此问题一定是文档库特有的。我是否需要将文档保存到 领域 在文档库中?

    更新2

    我也尝试过:

    string saveloc = String.Format(@"{0}\{1}", doclib, filename);
    

    …具有相同的结果。

    还有这个:

    string saveloc = String.Format(@"{0}\{1}\{2}", siteUrl, doclib, filename);
    

    ……这至少提供了一些多样性,“ URI无效:无法分析主机名。 "

    有了这个:

    string saveloc = String.Format("{0}/{1}/{2}", siteUrl, doclib, filename);
    

    ……我又回到了“发生I/O错误”这句老话。

    更新3

    由于Sharepoint网站的“AllItems.aspx”页面同时包含“文档”和“列表”,我想知道在这种情况下,我是否不应该使用列表,而是使用文档。IOW,也许我的代码应该是这样的:

    SPDocTemplateCollection spdoctemplatecoll = web.DocTemplates;
    SPDocumentLibrary spdoclib = spdoctemplatecoll[doclib];
    SPListItem spli = spdoclib.Items.Add();
    

    …当前位置:

    SPList list = web.Lists[doclib];
    SPListItem spli = list.Items.Add();
    SPListItem spli = list.Items.Add();
    

    …但这一猜测没有引起注意,因为它不会编译(我得到,“与‘Microsoft.SharePoint.SPDocTemplateCollection.this[int]’匹配的最佳重载方法具有一些无效参数”和“参数1:无法从‘string’转换为‘int’”)

    1 回复  |  直到 11 年前
        1
  •  0
  •   Community Mohan Dere    9 年前

    这是有效的:

    . . .
    SavePDFToDocumentLibrary(fileFullpath); // instead of trying to send the memory stream, using the file saved on the server
    . . .
    
    private void SavePDFToDocumentLibrary(String fullpath)
    {
        String fileToUpload = fullpath;
        String sharePointSite = siteUrl;
        String documentLibraryName = "DirectPayPDFForms";
    
        using (SPSite oSite = new SPSite(sharePointSite))
        {
            using (SPWeb oWeb = oSite.OpenWeb())
            {
                if (!System.IO.File.Exists(fileToUpload))
                {
                    throw new FileNotFoundException("File not found.", fileToUpload);
                }
    
                SPFolder doclib = oWeb.Folders[documentLibraryName];
    
                // Prepare to upload
                Boolean replaceExistingFiles = true;
                String fileName = System.IO.Path.GetFileName(fileToUpload);
                FileStream fileStream = File.OpenRead(fileToUpload);
    
                // Upload document
                SPFile spfile = doclib.Files.Add(fileName, fileStream, replaceExistingFiles);
    
                // Commit 
                doclib.Update();
            }
        }
    }
    

    我改编自亨利·祖奇尼的回答 here .