Sunday, March 14, 2010

Custom Web Service in MOSS 2007

It was a bad time for me when I was trying to run custom web service in Sharepoint. I was trying and trying and getting weird situations again and again. Anyway,finally it was done and I want to share it with others to save some of their time.

Step 1. Create an ASP.NET Web Service Application in VS 2008. Rename your Service1.asmx file and class name according to your desired name both in .cs file and in markup file.

There are no step 2 and 3, go to step 4 :)

Step 4. Create a strong name for the dll of your project. In Solution Explorer, right-click the web service project, and in the Properties dialog box, click Signing, select Sign the assembly, and select in the box and create a new strong name key file. Now build the project.

Step 5. Copy the .asmx file to C:\Inetpub\wwwroot. Open the file and delete this portion -


CodeBehind="YourService.asmx.cs"

Go to GAC, right click on your assembly and copy the publick key from properties. Your final markup looks like this.

<%@ WebService Language="C#" Class="YourService.YourService, YourService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=615f0967ce2cd86a" %>

Step 6. Now you have to create .disco and .wsdl files and modify them. There are two ways to do this - creating and modifying manually or using some tool. I prefer the second way but both are explained here.

First Method -
>Run the command in cmd -

set path=%path%;"C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin";.

> Now run this command in cmd -

Disco http://localhost/YourService.asmx

YourService.disco and YourService.wsdl files will be created.

>To register namespaces of the Windows SharePoint Services object model, open both the .disco and .wsdl files and replace the opening XML processing instruction -- -- 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"; %>

>In the .disco file, modify the contract reference and SOAP address tags to be like the following example, which replaces literal paths with code generated paths through use of the Microsoft.SharePoint.Utilities.SPEncode class, and which replaces the method name that is specified in the binding attribute:


<contractref ref="&lt;%" wsdl="" output="" docref="&lt;%" xmlns="http://schemas.xmlsoap.org/disco/scl/"><soap address="&lt;%" q1="http://tempuri.org" binding="q1:FilesSoap" xmlns="http://schemas.xmlsoap.org/disco/soap/"><soap address="&lt;%" q2="http://tempuri.org" binding="q2:FilesSoap12" xmlns="http://schemas.xmlsoap.org/disco/soap/">

> In the .wsdl file, make the following, similar substitution for the SOAP address that is specified:


<soap:address location="&lt;%">

>Make the following substitution for the SOAP12 address:


<soap12:address location="&lt;%">

> Rename both files in the respective formats YourServicedisco.aspx and YourServicewsdl.aspx so that your service is discoverable through SharePoint.

Second Method -
>Go to the link http://www.codeproject.com/KB/XML/wss_web_service_helper.aspx and download the tool.

>Use the tool to create YourServicedisco.aspx and YourServicewsdl.aspx files.

Step 7. Now you copy YourServicedisco.aspx,YourServicewsdl.aspx and YourService.asmx files to _vti_bin virtual directory which maps physically to the C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\ISAPI directory, which contains the default Web service files used in Windows SharePoint Services.

Step 8. To make your Web service discoverable in Visual Studio as a Web service alongside the default Windows SharePoint Services Web services, open the spdisco.aspx file located in C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\ISAPI and add the following code, specifying the .asmx file for your Web service.


<contractRef ref=<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(spWeb.Url + "/_vti_bin/YourService.asmx?wsdl"), Response.Output); %>
docRef=<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(spWeb.Url + "/_vti_bin/YourService.asmx"), Response.Output); %>
xmlns=" http://schemas.xmlsoap.org/disco/scl/ " />
<discoveryRef ref=<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(spWeb.Url + "/_vti_bin/YourService.asmx?disco"),Response.Output); %>
xmlns="http://schemas.xmlsoap.org/disco/" />

Step 9. Now go to the link http://yoursite:port_number/_vti_bin/yourservice.asmx. You will see the functions of web service listed in the page.

Step 10. Click a function to see it's Soap. You have to use this soap to call the web service method and retrieve it's returned value.

Here I am giving a jquery example of calling and displaying the data using the soap.

Soap Request

<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<HelloWorld xmlns="http://tempuri.org/" />
</soap:Body>
</soap:Envelope>


Soap Response

<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<HelloWorldResponse xmlns="http://tempuri.org/">
<HelloWorldResult>string</HelloWorldResult>
</HelloWorldResponse>
</soap:Body>
</soap:Envelope>

Just create a Content Editor web part and paste this code to call the Web Service.



<script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js"></script>
<script type="text/javascript">
function btnClicked(){

var soapEnv =
"<soap:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>\
<soap:Body>\
<NewMethod xmlns='http://tempuri.org/'>\
<test>"+'Test'+"</test>\
</NewMethod>\
</soap:Body>\
</soap:Envelope>";

$.ajax({
url: "_vti_bin/SPWSData.asmx",
type: "POST",
dataType: "xml",
data: soapEnv,
complete: processResult,
contentType: "text/xml; charset=\"utf-8\""
});
}

function processResult(xData, status) {
alert(status);
$(xData.responseXML).find("NewMethodResult").each(function()
{
var data = $(this).text();
alert(data);
});
}
</script>

<input type="button" onclick="btnClicked()" value="Click"/>

Ok,this is all about creating and hosting custom web service in MOSS 2007

No comments: