Writing Custom Web Services for SharePoint Products and Technologies - Microsoft Typo...

Published 26 April 08 01:22 PM | jacobl 

Writing a custom web service for SharePoint, I ran into these two great articles which walked me through the process, but it still wasn't enough to tame the beast. Check out Writing Custom Web Services for SharePoint Products and Services on MSDN and Creating a Custom Web Service for SharePoint on ITToolbox, but take heed; there are typos that will burn you. I'm contacting the authors of these articles and will post here again once they are fixed. For now, here is what I did to get past them. Join me in a journey of pain followed by triumph.

I started off my webservice-writing extravaganza by modeling it directly after the example at MSDN. I was able to get pretty far. I had my disco, wsdl, dll, and asmx files, and placed them in the mapped _vti_bin directory like a good doobie. I registered the assembly as a safe control and added it to the spsdisco.aspx file as the tutorial said, but no luck. I kept getting the vanilla error page produced by SharePoint. I looked through my Error log to find nothing and went back to staring at the seemingly useless error page. Then, ah yes, look at the url. It ain't pretty, but the URL in the address bar had some useful information. What a convenient place to put that!

This is what I had to go on: http://localhost/_layouts/error.aspx?ErrorText=File%20Not%20Found%2E

I ran Procmon and found out that SharePoint wasn't looking for the assembly where I thought it would. To prove that right, I assumed... put it in the GAC. I know, not the best practice, but I wanted to get it working and then fix it for real later.

I dragged my assembly into %WINDOWS%\assembly only to find out that my assembly was not signed. This is a necessary step to getting your stuff to work with SharePoint. So after signing it, I put it in the GAC, only to get the same error...

I ran Procmon again and found out that SharePoint wasn't looking in the GAC either! Interesting... I then did some Googling and found the article on ITToolbox. It was basically a revamped version of the article on MSDN. This article gave a few options of where you could/should put the assembly and I settled on the bin of the virtual directory I was deploying to. The asmx file loaded in IE! I was in the clear! Right? ... Wrong.

I opened the project that would be using the service, attempted to add it as a Web Reference and it errored out. I tried to load Service1wsdl.aspx up in IE and I got another URL based error saying, "the given assembly name or codebase was invalid exception from hresult 80131047 sharepoint web service". Ok, something with more substance at least. There must be something wrong in the wsdl file.

The best thing I felt I could do in this situation is examine every line of the wsdl (there are only 4, heh). I compared it directly to one I knew was working; the Microsoft-provided Listswsdl.aspx file for the Lists web service.

Here's the first line of my file:

<%@ Page Language="C#" Inherits="System.Web.UI.Page" %> <%@ Assembly Name="Microsoft.SharePoint, Microsoft.SharePoint, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Import Namespace="Microsoft.SharePoint.Utilities" %> <%@ Import Namespace="Microsoft.SharePoint" %> <% Response.ContentType = "text/xml"; %>

And here's the first line of the Listswsdl.aspx file:

<%@ 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"; %>

There are two differences here. The version number in the first snippet is 11.0.0.0 while it is 12.0.0.0 in Microsoft's (this actually doesn't matter because there are version redirects in the SharePoint web.configs) and the assembly name incorrectly includes the namespace when it is already mentioned in the later Import statements.

...Name="Microsoft.SharePoint, Microsoft.SharePoint, Version...

should read

...Name="Microsoft.SharePoint, Version...

Thanks Microsoft, that was your bad. Maybe that flew with Version 11.0.0.0, but 12.0.0.0 no likey.

Excellent. The wsdl loaded! Before I got too excited, I opened the disco file in Notepad to make sure that Microsoft didn't burn me there too with the bad Assembly Name tag. They did, I fixed that and moved on.

I tried to load the disco in IE and ugh, another error: httpresponse.output cannot be assigned to it is read only. With this new tidbit, I decided to look for all the references to response.output in the disco file and compare it to the same references in the Listsdisco.aspx file that Microsoft wrote.

This was my disco file:

<contactRef 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/" /> xmlns:q1="http://tempuri.org" binding="q1:FilesSoap" xmlns="http://schemas.xmlsoap.org/disco/soap/" /> xmlns:q2="http://tempuri.org" binding="q2:FilesSoap12" xmlns="http://schemas.xmlsoap.org/disco/soap/" />

and this is the fixed copy after comparing it to the Listsdisco.aspx

<contactRef 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/" /> xmlns:q1="http://tempuri.org" binding="q1:FilesSoap" xmlns="http://schemas.xmlsoap.org/disco/soap/" /> xmlns:q2="http://tempuri.org" binding="q2:FilesSoap12" xmlns="http://schemas.xmlsoap.org/disco/soap/" />

Notice anything?

...Response.Output=""...

should read

...Response.Output...

This was in the example provided by the ITToolbox site. I'm not sure when I decided to go with their example for that line, but I did... and got burned.

After that last fix, the disco loaded in IE without a problem and I was able to add the service to my project as a Web Reference without a problem.

 

Comments

# DotNetKicks.com said on April 25, 2008 12:50 PM:

You've been kicked (a good thing) - Trackback from DotNetKicks.com

Anonymous comments are disabled