Reputation: 325
I have been trying to add new list items with attachments
to my list .
The list items are added fine, however I cannot figure out how to attach files to those items
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ConsoleApplication3.TestReference;
using System.IO;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
MVSDataContext dc = new MVSDataContext(
new Uri("https:xxx_vti_bin/ListData.svc"));
dc.Credentials = System.Net.CredentialCache.DefaultCredentials;
TestListItem newItem = new TestListItem { Title = "test6" };
dc.AddToTestList(newItem);
dc.SaveChanges();
/* up to this point everything works fine and i am able to add a new list item */
FileStream fStream = File.OpenRead("C:\\xxxxx.xlsx");
string fileName = fStream.Name.Substring(3);
byte[] contents = new byte[fStream.Length];
fStream.Read(contents, 0, (int)fStream.Length);
fStream.Close();
/* the file read successfuly . Now I should use `contents` to upload the file */
newItem.Attachments.Add(fStream.Name, contents); /* This line does not compile */
dc.SaveChanges();
}
}
}
}
I also tried approach from here
DirectoryInfo attachmentDirectory = new DirectoryInfo(@"C:\xxx");
FileInfo[] attachments = attachmentDirectory.GetFiles();
foreach (FileInfo attachment in attachments)
{
FileStream fs = new FileStream(attachment.FullName, FileMode.Open, FileAccess.Read);
// Create a byte array of file stream length
byte[] ImageData = new byte[fs.Length];
//Read block of bytes from stream into the byte array
fs.Read(ImageData, 0, System.Convert.ToInt32(fs.Length));
//Close the File Stream
fs.Close();
newItem.Attachments.Add(attachment.Name, ImageData);
}
However got the same error
How can I make an attachment to a list item ?
Here is the TestListItem class
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.18052
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
// Original file name:
// Generation date: 1/30/2014 11:00:30 AM
namespace ConsoleApplication3.TestReference
{
/// <summary>
/// There are no comments for MVSDataContext in the schema.
/// </summary>
public partial
class MVSDataContext : global::System.Data.Services.Client.DataServiceContext
{
/// <summary>
/// Initialize a new MVSDataContext object.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
public MVSDataContext(global::System.Uri serviceRoot) :
base(serviceRoot)
{
this.ResolveName = new global::System.Func<global::System.Type, string>(this.ResolveNameFromType);
this.ResolveType = new global::System.Func<string, global::System.Type>(this.ResolveTypeFromName);
this.OnContextCreated();
}
partial void OnContextCreated();
/// <summary>
/// Since the namespace configured for this service reference
/// in Visual Studio is different from the one indicated in the
/// server schema, use type-mappers to map between the two.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
protected global::System.Type ResolveTypeFromName(string typeName)
{
if (typeName.StartsWith("Microsoft.SharePoint.DataService", global::System.StringComparison.Ordinal))
{
return this.GetType().Assembly.GetType(string.Concat("ConsoleApplication3.TestReference", typeName.Substring(32)), false);
}
return null;
}
/// <summary>
/// Since the namespace configured for this service reference
/// in Visual Studio is different from the one indicated in the
/// server schema, use type-mappers to map between the two.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
protected string ResolveNameFromType(global::System.Type clientType)
{
if (clientType.Namespace.Equals("ConsoleApplication3.TestReference", global::System.StringComparison.Ordinal))
{
return string.Concat("Microsoft.SharePoint.DataService.", clientType.Name);
}
return null;
}
/// <summary>
/// There are no comments for Attachments in the schema.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
public global::System.Data.Services.Client.DataServiceQuery<AttachmentsItem> Attachments
{
get
{
if ((this._Attachments == null))
{
this._Attachments = base.CreateQuery<AttachmentsItem>("Attachments");
}
return this._Attachments;
}
}
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
private global::System.Data.Services.Client.DataServiceQuery<AttachmentsItem> _Attachments;
/// <summary>
/// There are no comments for MasterPageGallery in the schema.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
public global::System.Data.Services.Client.DataServiceQuery<MasterPageGalleryItem> MasterPageGallery
{
get
{
if ((this._MasterPageGallery == null))
{
this._MasterPageGallery = base.CreateQuery<MasterPageGalleryItem>("MasterPageGallery");
}
return this._MasterPageGallery;
}
}
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
private global::System.Data.Services.Client.DataServiceQuery<MasterPageGalleryItem> _MasterPageGallery;
/// <summary>
/// There are no comments for MasterPageGalleryCompatibleUIVersionS in the schema.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
public global::System.Data.Services.Client.DataServiceQuery<MasterPageGalleryCompatibleUIVersionSValue> MasterPageGalleryCompatibleUIVersionS
{
get
{
if ((this._MasterPageGalleryCompatibleUIVersionS == null))
{
this._MasterPageGalleryCompatibleUIVersionS = base.CreateQuery<MasterPageGalleryCompatibleUIVersionSValue>("MasterPageGalleryCompatibleUIVersionS");
}
return this._MasterPageGalleryCompatibleUIVersionS;
}
}
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
private global::System.Data.Services.Client.DataServiceQuery<MasterPageGalleryCompatibleUIVersionSValue> _MasterPageGalleryCompatibleUIVersionS;
/// <summary>
/// There are no comments for TestList in the schema.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
public global::System.Data.Services.Client.DataServiceQuery<TestListItem> TestList
{
get
{
if ((this._TestList == null))
{
this._TestList = base.CreateQuery<TestListItem>("TestList");
}
return this._TestList;
}
}
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
private global::System.Data.Services.Client.DataServiceQuery<TestListItem> _TestList;
/// <summary>
/// There are no comments for UserInformationList in the schema.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
public global::System.Data.Services.Client.DataServiceQuery<UserInformationListItem> UserInformationList
{
get
{
if ((this._UserInformationList == null))
{
this._UserInformationList = base.CreateQuery<UserInformationListItem>("UserInformationList");
}
return this._UserInformationList;
}
}
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
private global::System.Data.Services.Client.DataServiceQuery<UserInformationListItem> _UserInformationList;
/// <summary>
/// There are no comments for Attachments in the schema.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
public void AddToAttachments(AttachmentsItem attachmentsItem)
{
base.AddObject("Attachments", attachmentsItem);
}
/// <summary>
/// There are no comments for MasterPageGallery in the schema.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
public void AddToMasterPageGallery(MasterPageGalleryItem masterPageGalleryItem)
{
base.AddObject("MasterPageGallery", masterPageGalleryItem);
}
/// <summary>
/// There are no comments for MasterPageGalleryCompatibleUIVersionS in the schema.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
public void AddToMasterPageGalleryCompatibleUIVersionS(MasterPageGalleryCompatibleUIVersionSValue masterPageGalleryCompatibleUIVersionSValue)
{
base.AddObject("MasterPageGalleryCompatibleUIVersionS", masterPageGalleryCompatibleUIVersionSValue);
}
/// <summary>
/// There are no comments for TestList in the schema.
/// </summary>
..............
Upvotes: 0
Views: 3966
Reputation: 136
Hope this helps other users.
The problem here is that the SharePoint Client Object Model does not create the item's sub-folder under the Attachments folder.
To solve this you should use the "/_vti_bin/lists.asmx"
web service by adding a Web Service Reference, please follow this link in case you need indications to achieve it.
using FR.WssODataCore.ListsWebService;
Once you added the reference to your service you can just use this code snippet:
var listsServiceClient = new Lists
{
Credentials = defaultContext.Credentials,
Url = siteCollectionUrl + "/_vti_bin/lists.asmx"
};
listsServiceClient.AddAttachment(currentListName, listItemId, fileName, fileContent);
Where siteCollectionUrl
is your service's url like http://yourSite.ext/webName, and defaultContext
is an instance of Microsoft.SharePoint.Client
which I've used to complete other actions.
Please, note that you need a reference to your web service reference that contains the Lists
object
using MyServiceNameSpace.ListsWebService;
In this way, I was able to use both the ListData.svc
and Lists.asmx
endpoints by combining the operations, using the .asmx service only to upload the attachment.
Here another good resource.
Upvotes: 1
Reputation: 10287
Call the Method AddQueryOption instead of Add:
newItem.Attachments.Add(fStream.Name, contents); /* This line does not compile */
newItem.Attachments.AddQueryOption(fStream.Name, contents); /* This line does compile */
Upvotes: 1
Reputation:
Have you got the code for TestListItem? It looks pretty clearly like Add requires 2 arguments to be passed into it.
You need to add the byte stream for the file you want to add - see here
foreach (FileInfo attachment in attachments)
{
FileStream fs = new FileStream(attachment.FullName , FileMode.Open,FileAccess.Read);
// Create a byte array of file stream length
byte[] ImageData = new byte[fs.Length];
//Read block of bytes from stream into the byte array
fs.Read(ImageData,0,System.Convert.ToInt32(fs.Length));
//Close the File Stream
fs.Close();
item.Attachments.Add(attachment.Name, ImageData);
}
Upvotes: 2