2010-06-03 110 views
13

我有一個SharePoint列表,我使用客戶端對象模型添加了新的ListItems。 添加ListItems不是問題,效果很好。SharePoint 2010 - 客戶端對象模型 - 將附件添加到ListItem

現在我想添加附件。

我以下列方式使用SaveBinaryDirect:

File.SaveBinaryDirect(clientCtx, url.AbsolutePath + "/Attachments/31/" + fileName, inputStream, true); 

只要它工作沒有任何問題,因爲我想要添加附件的項目,已經有已添加的附件通過SharePoint網站而不使用客戶端對象模型。

當我嘗試添加附件的項目,這並不具有任何附件,但是,我得到以下錯誤(均發生,但沒有使用相同的文件 - 而這兩個消息持續出現):

The remote server returned an error: (409) Conflict
The remote server returned an error: (404) Not Found

我想,也許我需要爲這個項目首先創建附件文件夾。 當我嘗試下面的代碼:

clientCtx.Load(ticketList.RootFolder.Folders); 
clientCtx.ExecuteQuery(); 
clientCtx.Load(ticketList.RootFolder.Folders[1]);    // 1 -> Attachment folder 
clientCtx.Load(ticketList.RootFolder.Folders[1].Folders); 
clientCtx.ExecuteQuery(); 
Folder folder = ticketList.RootFolder.Folders[1].Folders.Add("33"); 
clientCtx.ExecuteQuery(); 

我收到一條錯誤消息說:

Cannot create folder "Lists/Ticket System/Attachment/33"

我對SharePoint網站/列表完全的管理員權限。

任何想法我可能做錯了什麼?

感謝,Thorben

回答

9

我已經討論了與微軟的這個問題。看起來像只有一種方法來遠程創建附件是List.asmx Web服務。我試圖創建這個子文件夾也沒有成功。

+0

感謝您的回答,MaxBeard。至少知道這是不可能的,比嘗試和失敗要好 - 似乎應該是可能的。順便說一句,好的博客。 – Thorben 2010-06-18 15:48:19

+0

這似乎確實如此...請參閱我的答案,瞭解如何完成此操作的完整代碼示例。 – 2013-03-06 13:44:29

4

它反映了相當差於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)一_web_reference_我叫SP2010是從的URL創建:HTTP:// /_vti_bin/Lists.asmx

苯教機會......

12

我掙扎了很久這個問題了,所以我想我會發布展示如何完整的代碼示例成功創建列表項並添加附件。

我使用的客戶端對象API創建列表項和SOAP Web服務來添加附件。這是因爲,正如Web上其他地方所述,客戶端對象API只能用於將附件添加到項目上載目錄已存在的項目(例如,項目已有附件)。否則它會失敗,併發生409錯誤或其他問題。儘管如此,SOAP Web服務可以應付這個問題。

需要注意的是另一件事我必須克服的是,即使我使用下面的URL添加的SOAP參考:

https://my.sharepoint.installation/personal/test/_vti_bin/lists.asmx

即VS實際添加到的app.config的網址是:

https://my.sharepoint.installation/_vti_bin/lists.asmx

我不得不手動更改的app.config回正確的URL,否則我會得到錯誤:

List does not exist. The page you selected contains a list that does not exist. It may have been deleted by another user. 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)); 
    } 

希望這可以幫助別人。

+1

謝謝。這爲我做了。 – 2013-04-08 16:33:18

+0

我正在使用Visual Studio 2012並嘗試將列表項附件保存到SharePoint 2010中。我的SharePoint 2010服務器上的代理類和方法與上述示例相匹配,找不到任何Web服務。 – Zarepheth 2013-10-24 23:40:38

+2

好吧,我發現我的問題。在Visual Studio 2012中,必須添加「Web引用」而不是「服務引用」。從「添加服務參考」對話框中,單擊「高級...」按鈕。然後點擊「添加Web引用...」按鈕。現在顯示早期版本的Visual Studio中熟悉的「添加Web引用」對話框。 – Zarepheth 2013-10-24 23:56:47

0

我已經使用和試過這一個對我的COM應用程序,它爲我的作品

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

注意:只有在項目文件夾已被創建

5

與2010年的SharePoint工作沒有辦法使用COM將第一個附件上傳到列表項目。建議不要使用列表web服務。

隨着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 

這種方法在http://www.mailtosharepoint.net/

+0

非常感謝你。這適用於SharePoint(2013)Online和MVC應用程序。 – 2014-01-16 21:38:47

+0

@sam除非我錯過了某些東西,否則這似乎不起作用,除非您使用的是現有的ListItem。如果您通過AddItem方法創建一個新項目,這不起作用。這是拋出一個錯誤,說你必須先保存該項目,然後保存附件。 – Thierry 2017-06-02 16:05:37

+0

@sam,我收回它,它確實工作:)但不是你在你的代碼段中描述的方式。你需要添加這個項目,首先調用AddItem,然後調用'GetItemById'中的代碼,它確實工作得很好。 – Thierry 2017-06-02 16:23:25

0

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; 
} 
+0

只需發佈一段代碼並不能很好地回答問題。請解釋*您的解決方案如何解決OP的任務,以及它增加了問題中已有的其他答案。 – TZHX 2015-09-29 19:44:04

相關問題