为什么这个Sharepoint Files.Add()会导致I/O错误?

本文关键字:错误 Sharepoint Files Add 为什么 | 更新日期: 2023-09-27 18:05:14

使用下面的代码:

    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文件放在服务器上(但这不是我们想要的位置—我们需要它首先转到Document Library)。

更新

我得到了相同的异常,将上面有问题的代码块替换为调用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);
    }
}

这种类型的代码可以在另一个实例中工作(我可以通过这种方式成功地将值保存到List中),所以问题一定是特定于document - library的。是否需要将文档保存到文档库中的特定字段 ?

更新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

更新

自"AllItems."Sharepoint网站的aspx页面有"文档"answers"列表",我想知道我是否不应该在这种情况下使用列表,而是文档。现在,也许我的代码应该是这样的:

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]'有一些无效的参数"answers"参数1:不能从'string'转换为'int'")

为什么这个Sharepoint Files.Add()会导致I/O错误?

这行得通:

. . .
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();
        }
    }
}

我改编自Henry Zucchini的回答