Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# SharePoint 2010-客户端对象模型-向ListItem添加附件_C#_Sharepoint 2010_Client_Attachment_Listitem - Fatal编程技术网

C# SharePoint 2010-客户端对象模型-向ListItem添加附件

C# SharePoint 2010-客户端对象模型-向ListItem添加附件,c#,sharepoint-2010,client,attachment,listitem,C#,Sharepoint 2010,Client,Attachment,Listitem,我有一个SharePoint列表,我正在使用客户端对象模型向其中添加新的ListItems。 添加列表项不是问题,效果很好 现在我想添加附件 我以以下方式使用SaveBinaryDirect: File.SaveBinaryDirect(clientCtx, url.AbsolutePath + "/Attachments/31/" + fileName, inputStream, true); 只要我尝试将附件添加到的项目已具有通过SharePoint网站添加的附件且未使用客户端对象模型,它

我有一个SharePoint列表,我正在使用客户端对象模型向其中添加新的ListItems。 添加列表项不是问题,效果很好

现在我想添加附件

我以以下方式使用SaveBinaryDirect:

File.SaveBinaryDirect(clientCtx, url.AbsolutePath + "/Attachments/31/" + fileName, inputStream, true);
只要我尝试将附件添加到的项目已具有通过SharePoint网站添加的附件且未使用客户端对象模型,它就可以正常工作

当我尝试向一个还没有任何附件的项目添加附件时,我会出现以下错误(两个错误都会发生,但不会出现在相同的文件中-但这两条消息始终显示):

我收到一条错误消息,上面说: Cannot create folder "Lists/Ticket System/Attachment/33" 无法创建文件夹“列表/票证系统/附件/33”

我拥有SharePoint网站/列表的完全管理员权限

知道我做错了什么吗


谢谢,Thorben我已经和微软讨论过这个问题了。看起来远程创建附件的唯一方法是List.asmx web服务。我也尝试过创建此子文件夹,但没有成功。

这反映了Microsoft SharePoint团队对该问题的认识和解决方法的可用建议不够好。我是这样处理的:

我正在使用产品附带的新SharePoint 2010托管客户端。因此,我已经有了一个具有凭据的SharePoint ClientContext。以下函数用于向列表项添加附件:

private void SharePoint2010AddAttachment(ClientContext ctx, 
                                     string listName, string itemId, 
                                     string fileName, byte[] fileContent)
{
    var listsSvc = new sp2010.Lists();
    listsSvc.Credentials = _sharePointCtx.Credentials;
    listsSvc.Url = _sharePointCtx.Web.Context.Url + "_vti_bin/Lists.asmx";
    listsSvc.AddAttachment(listName, itemId, fileName, fileContent);
}
上述代码的唯一先决条件是向项目(我使用的是Visual Studio 2008)添加一个名为sp2010的“web参考”,它是从以下URL创建的:http:///_vti_bin/Lists.asmx


很有可能…

我也为这个问题挣扎了很长时间,所以我想发布一个完整的代码示例,展示如何成功创建列表项和添加附件

我使用客户机对象API创建列表项,使用SOAP web服务添加附件。这是因为,如web上其他地方所述,客户端对象API只能用于向已存在项目上载目录的项目添加附件(例如,如果项目已具有附件)。否则它会因为一个409错误或者别的什么而失败。soapweb服务可以处理这个问题

请注意,我必须克服的另一件事是,即使我使用以下URL添加了SOAP引用:

VS实际添加到app.config的URL为:

我必须手动将app.config更改回正确的URL,否则会出现错误:

列表不存在。 所选页面包含不存在的列表。它可能已被其他用户删除。 0x82000006

代码如下:

    void CreateWithAttachment()
    {
        const string listName = "MyListName";
        // set up our credentials
        var credentials = new NetworkCredential("username", "password", "domain");

        // create a soap client
        var soapClient = new ListsService.Lists();
        soapClient.Credentials = credentials;

        // create a client context
        var clientContext = new Microsoft.SharePoint.Client.ClientContext("https://my.sharepoint.installation/personal/test");
        clientContext.Credentials = credentials;

        // create a list item
        var list = clientContext.Web.Lists.GetByTitle(listName);
        var itemCreateInfo = new ListItemCreationInformation();
        var newItem = list.AddItem(itemCreateInfo);

        // set its properties
        newItem["Title"] = "Created from Client API";
        newItem["Status"] = "New";
        newItem["_Comments"] = "here are some comments!!";

        // commit it
        newItem.Update();
        clientContext.ExecuteQuery();

        // load back the created item so its ID field is available for use below
        clientContext.Load(newItem);
        clientContext.ExecuteQuery();

        // use the soap client to add the attachment
        const string path = @"c:\temp\test.txt";
        soapClient.AddAttachment(listName, newItem["ID"].ToString(), Path.GetFileName(path),
                                  System.IO.File.ReadAllBytes(path));
    }

希望这对其他人有所帮助。

我已经在我的CSOM(SharePoint客户端对象模型)应用程序上使用并尝试过这一功能,它对我很有用

using (ClientContext context = new ClientContext("http://spsite2010"))
                {

                    context.Credentials = new NetworkCredential("admin", "password");
                    Web oWeb = context.Web;
                    List list = context.Web.Lists.GetByTitle("Tasks");
                    CamlQuery query = new CamlQuery();
                    query.ViewXml = "<View><Where><Eq><FieldRef Name = \"Title\"/><Value Type=\"String\">New Task Created</Value></Eq></Where></View>";
                    ListItemCollection listItems = list.GetItems(query);
                    context.Load(listItems);
                    context.ExecuteQuery();
                    FileStream oFileStream = new FileStream(@"C:\\sample.txt", FileMode.Open);
                    string attachmentpath = "/Lists/Tasks/Attachments/" + listItems[listItems.Count - 1].Id + "/sample.txt";
                    Microsoft.SharePoint.Client.File.SaveBinaryDirect(context, attachmentpath, oFileStream, true);
                }
使用(ClientContext=newclientcontext(“http://spsite2010"))
{
context.Credentials=新的网络凭据(“管理员”、“密码”);
Web oWeb=context.Web;
List List=context.Web.Lists.GetByTitle(“任务”);
CamlQuery query=新建CamlQuery();
query.ViewXml=“新建任务已创建”;
ListItemCollection listItems=list.GetItems(查询);
加载(列表项);
context.ExecuteQuery();
FileStream oFileStream=新文件流(@“C:\\sample.txt”,FileMode.Open);
字符串attachmentpath=“/Lists/Tasks/Attachments/”+listItems[listItems.Count-1].Id+“/sample.txt”;
Microsoft.SharePoint.Client.File.SaveBinaryDirect(上下文,attachmentpath,oFileStream,true);
}

注意:仅当项目文件夹已使用Sharepoint 2010创建时才有效。无法使用COM将第一个附件上载到列表项目。建议使用列表web服务inmstead

使用Sharepoint 2013,它可以正常工作

AttachmentCreationInformation newAtt = new AttachmentCreationInformation();
newAtt.FileName = "myAttachment.txt";
// create a file stream
string fileContent = "This file is was ubloaded by client object meodel ";
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
byte[] buffer = enc.GetBytes(fileContent);
newAtt.ContentStream = new MemoryStream(buffer);

// att new item or get existing one
ListItem itm = list.GetItemById(itemId);
ctx.Load(itm);   
// do not execute query, otherwise a "version conflict" exception is rised, but the file         is uploaded
// add file to attachment collection
newAtt.ContentStream = new MemoryStream(buffer);
itm.AttachmentFiles.Add(newAtt); 
AttachmentCollection attachments = itm.AttachmentFiles;
ctx.Load(attachments);
ctx.ExecuteQuery(); 
// see all attachments for list item
// this snippet works if the list item has no attachments
此方法在HTML中使用:

<asp:FileUpload ID="FileUpload1" runat="server" AllowMultiple="true" />

代码隐藏中的事件:

protected void UploadMultipleFiles(object sender, EventArgs e)
{
    Common.UploadDocuments(Common.getContext(new Uri(Request.QueryString["SPHostUrl"]),
    Request.LogonUserIdentity), FileUpload1.PostedFiles, new CustomerRequirement(), 5);
}

public static List<string> UploadDocuments<T>(ClientContext ctx,IList<HttpPostedFile> selectedFiles, T reqObj, int itemID)
{
    List<Attachment> existingFiles = null;
    List<string> processedFiles = null;
    List<string> unProcessedFiles = null;
    ListItem item = null;
    FileStream sr = null;
    AttachmentCollection attachments = null;
    byte[] contents = null;
    try
    {
        existingFiles = new List<Attachment>();
        processedFiles = new List<string>();
        unProcessedFiles = new List<string>();
        //Get the existing item
        item = ctx.Web.Lists.GetByTitle(typeof(T).Name).GetItemById(itemID);
        //get the Existing attached attachments
        attachments = item.AttachmentFiles;
        ctx.Load(attachments);
        ctx.ExecuteQuery();
        //adding into the new List
        foreach (Attachment att in attachments)
            existingFiles.Add(att);
        //For each Files which user has selected
        foreach (HttpPostedFile postedFile in selectedFiles)
        {
            string fileName = Path.GetFileName(postedFile.FileName);
            //If selected file not exist in existing item attachment
            if (!existingFiles.Any(x => x.FileName == fileName))
            {
                //Added to Process List
                processedFiles.Add(postedFile.FileName);
            }
            else
                unProcessedFiles.Add(fileName);
        }
        //Foreach process item add it as an attachment
        foreach (string path in processedFiles)
        {
            sr = new FileStream(path, FileMode.Open);
            contents = new byte[sr.Length];
            sr.Read(contents, 0, (int)sr.Length);
            var attInfo = new AttachmentCreationInformation();
            attInfo.FileName = Path.GetFileName(path);
            attInfo.ContentStream = sr;
            item.AttachmentFiles.Add(attInfo);
            item.Update();
        }
        ctx.ExecuteQuery();
    }
    catch (Exception ex)
    {
        throw ex;
    }
    finally
    {
        existingFiles = null;
        processedFiles = null;
        item = null;
        sr = null;
        attachments = null;
        contents = null;
        ctx = null;

    }
    return unProcessedFiles;
}
受保护的无效上载多文件(对象发送方,事件参数e)
{
Common.UploadDocuments(Common.getContext(新Uri(Request.QueryString[“SPHostUrl]”)),
Request.LogonUserIdentity),FileUpload1.PostedFiles,new CustomerRequirement(),5);
}
公共静态列表上载文档(ClientContext ctx、IList selectedFiles、T reqObj、int itemID)
{
列出现有文件=空;
List processedFiles=null;
列出未处理的文件=空;
ListItem=null;
FileStream sr=null;
AttachmentCollection attachments=null;
字节[]内容=空;
尝试
{
existingFiles=新列表();
processedFiles=新列表();
未处理的文件=新列表();
//获取现有项
item=ctx.Web.Lists.GetByTitle(typeof(T).Name.GetItemById(itemID);
//获取现有的附加附件
附件=item.AttachmentFiles;
载重量(附件);
ctx.ExecuteQuery();
//添加到新列表中
foreach(附件中的附件att)
现有文件。添加(附件);
//对于用户选择的每个文件
foreach(所选文件中的HttpPostedFile postedFile)
{
字符串文件名=Path.GetFileName(postedFile.fileName);
//如果所选文件不存在于现有项目附件中
如果(!existingFiles.Any(x=>x.FileName==FileName))
{
//已添加到进程列表中
processedFiles.Add(postedFile.FileName);
}
其他的
未处理的文件。添加(文件名);
}
//Foreach流程项将其添加为附件
foreach(pr中的字符串路径
AttachmentCreationInformation newAtt = new AttachmentCreationInformation();
newAtt.FileName = "myAttachment.txt";
// create a file stream
string fileContent = "This file is was ubloaded by client object meodel ";
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
byte[] buffer = enc.GetBytes(fileContent);
newAtt.ContentStream = new MemoryStream(buffer);

// att new item or get existing one
ListItem itm = list.GetItemById(itemId);
ctx.Load(itm);   
// do not execute query, otherwise a "version conflict" exception is rised, but the file         is uploaded
// add file to attachment collection
newAtt.ContentStream = new MemoryStream(buffer);
itm.AttachmentFiles.Add(newAtt); 
AttachmentCollection attachments = itm.AttachmentFiles;
ctx.Load(attachments);
ctx.ExecuteQuery(); 
// see all attachments for list item
// this snippet works if the list item has no attachments
<asp:FileUpload ID="FileUpload1" runat="server" AllowMultiple="true" />
protected void UploadMultipleFiles(object sender, EventArgs e)
{
    Common.UploadDocuments(Common.getContext(new Uri(Request.QueryString["SPHostUrl"]),
    Request.LogonUserIdentity), FileUpload1.PostedFiles, new CustomerRequirement(), 5);
}

public static List<string> UploadDocuments<T>(ClientContext ctx,IList<HttpPostedFile> selectedFiles, T reqObj, int itemID)
{
    List<Attachment> existingFiles = null;
    List<string> processedFiles = null;
    List<string> unProcessedFiles = null;
    ListItem item = null;
    FileStream sr = null;
    AttachmentCollection attachments = null;
    byte[] contents = null;
    try
    {
        existingFiles = new List<Attachment>();
        processedFiles = new List<string>();
        unProcessedFiles = new List<string>();
        //Get the existing item
        item = ctx.Web.Lists.GetByTitle(typeof(T).Name).GetItemById(itemID);
        //get the Existing attached attachments
        attachments = item.AttachmentFiles;
        ctx.Load(attachments);
        ctx.ExecuteQuery();
        //adding into the new List
        foreach (Attachment att in attachments)
            existingFiles.Add(att);
        //For each Files which user has selected
        foreach (HttpPostedFile postedFile in selectedFiles)
        {
            string fileName = Path.GetFileName(postedFile.FileName);
            //If selected file not exist in existing item attachment
            if (!existingFiles.Any(x => x.FileName == fileName))
            {
                //Added to Process List
                processedFiles.Add(postedFile.FileName);
            }
            else
                unProcessedFiles.Add(fileName);
        }
        //Foreach process item add it as an attachment
        foreach (string path in processedFiles)
        {
            sr = new FileStream(path, FileMode.Open);
            contents = new byte[sr.Length];
            sr.Read(contents, 0, (int)sr.Length);
            var attInfo = new AttachmentCreationInformation();
            attInfo.FileName = Path.GetFileName(path);
            attInfo.ContentStream = sr;
            item.AttachmentFiles.Add(attInfo);
            item.Update();
        }
        ctx.ExecuteQuery();
    }
    catch (Exception ex)
    {
        throw ex;
    }
    finally
    {
        existingFiles = null;
        processedFiles = null;
        item = null;
        sr = null;
        attachments = null;
        contents = null;
        ctx = null;

    }
    return unProcessedFiles;
}