Creating a Custom Web Service in SharePoint for Uploading Document

We had a requirement to upload the document to SharePoint document library whenever a file has been attached to our entities in Microsoft Dynamics CRM. So the obvious way of doing that was to use web service within the CRM. We had already written a utility using SharePoint Object Model that would be doing so. So we thought of reusing the existing logic defined over there and wrap it inside one our custom web service’s method. We created the web service and we deployed it in our SharePoint Server but outside the context of the SharePoint i.e. as a separate web site. However when trying to use that web service from other machines we ran into security issues, it was always giving Unauthorized Access error. We tried running the web service app pool with identity of administrator and also tried out impersonation defined through web.config again passing the account of administrator. But it didn’t work

Then finally tried out this article within MSDN which guides us on creating a web service that operates within the context of WSS 3.0.

http://msdn.microsoft.com/en-us/library/ms464040.aspx

Basic steps for creating a custom web service are following

1) Create a new asp.net web service project.

2) Add a new class library project in that solution.

3) Move Service1.cs file from web service project to class library project

4) Delete the Service1.cs file in web service project and class1.cs file in the class library project.

5) Put your custom logic in service.cs file that is now in the class library project.

6) Give strong name to the class library i.e. Sign the assembly.

7) Put the assembly in GAC. Get its public key token.

8) Now make modification to the service.asmx to use the assembly.

9) Replace code behind attribute with the class attribute to refer to the assembly

<%@ WebService Language=“C#” Class=“Service, MyServiceAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8f2dca3c0f2d0131” %>

10) Generate static discovery and wsdl file.

11) Copy the .asmx file of the Web service to \Program FilesCommon FilesMicrosoft Sharedweb server extensions12TEMPLATELAYOUTS

12) From visual studio command prompt run the following command

disco http://MyServer:port/_layouts/MyCustomWebService.asmx

13) open both the .disco and .wsdl files and replace the opening XML processing instruction — <?xml version="1.0" encoding="utf-8"?> — with instructions such as the following

<%@ Page Language=“C#” Inherits=“System.Web.UI.Page” %>

<%@ Assembly Name=“Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c” %>

<%@ Import Namespace=“Microsoft.SharePoint.Utilities” %>

<%@ Import Namespace=“Microsoft.SharePoint” %>

<% Response.ContentType = “text/xml”; %>

14) In the .disco file, modify the contract reference and SOAP address tags

<contractRef ref=<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(SPWeb.OriginalBaseUrl(Request) + “?wsdl”),Response.Output); %>

docRef=<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(SPWeb.OriginalBaseUrl(Request)),Response.Output); %>

xmlns=http://schemas.xmlsoap.org/disco/scl/&#8221; />

<soap address=<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(SPWeb.OriginalBaseUrl(Request)),Response.Output); %>

xmlns:q1=http://tempuri.org/&#8221; binding=“q1:HelloWorld” xmlns=http://schemas.xmlsoap.org/disco/soap/&#8221; />

<soap address=<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(SPWeb.OriginalBaseUrl(Request)),Response.Output); %>

xmlns:q2=http://tempuri.org/&#8221; binding=“q2:ServiceSoap12” xmlns=http://schemas.xmlsoap.org/disco/soap/&#8221; />

15) In the .wsdl file, make the following changes for the SOAP address

<soap:address location=<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(SPWeb.OriginalBaseUrl(Request)),Response.Output); %> />

16) Rename both files in the respective formats MyCustomWebServicedisco.aspx and MyCustomWebServicewsdl.aspx so that your service is discoverable through Windows SharePoint Services.

17) Copy the new MyCustomWebServicewsdl.aspx and MyCustomWebServicedisco.aspx files, and also the MyCustomWebService.asmx fil to _Drive:Program FilesCommon FilesMicrosoft SharedWeb Server Extensions12ISAPI directory

18) Open the spdisco.aspx files located in Program FilesCommon FilesMicrosoft SharedWeb Server Extensions12ISAPI and add the following code, specifying the .asmx file for your Web service.

<contractRef ref=<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(spWeb.Url + “/_vti_bin/MyCustomWebService.asmx?wsdl), Response.Output); %>

docRef=<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(spWeb.Url + “/_vti_bin/MyCustomWebService.asmx), Response.Output); %>

xmlns=http://schemas.xmlsoap.org/disco/scl/ />

<discoveryRef ref=<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(spWeb.Url + “/_vti_bin/MyCustomWebService.asmx?disco),Response.Output); %>

xmlns=http://schemas.xmlsoap.org/disco/&#8221; />

Any modification done to the custom logic would require putting the new assembly in GAC followed by generating the static disco and wsdl file and making all the necessary modification in disco and wsdl file as mentioned in the above steps.

Now in our case finally putting the custom logic of uploading the document within the class library for the web service helped us to solve the issues that we were facing.

[WebMethod]

public string UploadDocumentToSharePoint(string fileName, byte[] fileContents, string folderName)

{

if (fileContents == null)

{

return “Null Attachment”;

}

try

{

SPWeb web = SPContext.Current.Web;

web.AllowUnsafeUpdates = true;

SPFolder folder = web.GetFolder(folderName);

string fileURL = fileName;

folder.Files.Add(fileURL, fileContents);

return “File added successfully!”;

}

catch (System.Exception ex)

{

return “Error: “ + ex.Source + “| Message: “ + ex.Message;

}

}

And this is how we used it in within our custom application after adding the web reference to it.

FileStream oFileStream = File.OpenRead(@”C:g.doc”);

byte[] content = new byte[oFileStream.Length];

// store the contents in a byte array

oFileStream.Read(content, 0, (int)oFileStream.Length);

// close the stream

oFileStream.Close();

// instantiate the service

DocService.Service docService = new DocService.Service();

// pass the current logged in user credentials

docService.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;

// pass the name of the doc, content and document library name

string message = docService.UploadDocumentToSharePoint(“G1.doc”, content, “CrmDoc”);

MessageBox.Show(message);

Bye…


Author: Nishant Rana

I love working in and sharing everything about Microsoft.NET technology !

7 thoughts on “Creating a Custom Web Service in SharePoint for Uploading Document”

  1. hi Nishant
    i want to design a seating arrangement plan and also integrate it in MS CRM. due have any free sample code or a link that will me help in solving the same. please send me the link as soon as possible, i will wait hope u understand the problem. i m unable in designing the page integration is so far can u help me.
    please send me any help and hope u will in touch shortly with me my id is abhipandey_24@yahoo.com

    thanks
    abhi

    Like

  2. hi
    i want to integrate the feedback form with MS CRM 4.0 means when i enter the data from feedback form it enter in ms crm. can u help me out from the problem please send me link or any other material that help me in solving this problems. plz send it to my id ermanishtyagi@gmail.com

    Like

  3. I have 3 machines in one domain. 1 – Sharepoint server with service, 2 – machine with custom ASP.NET application, 3 – client machine. On the 3 machine I get the “Unauthorized” error. On the 2 all works. How to resolve that?

    Like

Share your thoughts

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s