Aleksei Nikolaevich
Aleksei Nikolaevich

Reputation: 325

Attachments using C# to Sharepoint

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

Answers (3)

Richard
Richard

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

Tamir Vered
Tamir Vered

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

user2046117
user2046117

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

Related Questions