Recently I was asked if there was a way to retrieve and present XML from a list. This of course is very straight forward but the complication here was that it needed to be available to an anonymous user who would consume the XML stream.
After a little thought I decided that we could use the "owssvr.dll" method. For those that have not used this before it is very simple. You make a call to the following URL:
http://{siteurl}/_vti_bin/owssvr.dll
Pass it a few parameters and then an XML stream is returned. So to test this I used the posts list on my blog with the following URL:
http://www.helloitsliam.com/_vti_bin/owssvr.dll?Cmd=Display&List={A462AB0D-84CF-4918-9950-D562530A5377}&XMLDATA=TRUE
The GUID that you pass is the actual GUID for the list that you wish to retrieve the data from. I tried this and all worked well until I tried it as an anonymous user to the site. When I tried it as a logged in user it came back with a blank page. Very strange I thought, but then I realized that a limitation of this method is lookup fields. When I tried it as an Anonymous user it simply kept prompting me again and again for permissions and then failed with an access denied error.
So this approach for me did not work. If you do want to use it and you are going to consume it internally then it is perfect and renders as you need it too. Below is sample output:
So what do I try next, I thought about building a custom web service but didn't really want to go to all that trouble so I decided to create a custom HttpHandler instead. This seemed a very simple and straight forward way of achieving this. Also it would give the ability to retrieve the XML from a list and the selected View that was created.
So let's create a custom HttpHandler for this. For this you won't even need to use Visual Studio. I use Notepad++ and created a file called "GetListXML.ashx". I then started to add the following code:
As note here make sure that the class element is the same name as the actual class listed below, sounds silly I know but it will never work otherwise. I then created the class as shown below:
Once the class is created we then need to add a "ProcessRequest" method which will run the core code.
The key here is to make sure we grab the current context, so we can then declare some variables that read the "Request" object.
For this to work I needed to pass it a Site URL, List ID and an ID for the selected View. To find these out I used the SharePoint UI or you could use a simple tool like this one:
http://blogs.msdn.com/ronalus/archive/2007/09/08/a-little-guid-picker.aspx
So now we need to add the following code so it will return the required XML.
So now we have the code completed, obviously there is more code here such as a "try {} catch {}" block etc. Now we have created the file, we save it and add it to the "_vti_bin" directory.
C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\ISAPI
Once in there we can then call it with the following syntax:
http://{SiteUrl}/_vti_bin/GetListXML.ashx?SiteURL={ActualSiteUrl}&ListID={ListGuid}&ViewID={ViewGuid}
When I ran this for my blog site I thought I would test it using the list that would not work with the "owssvr.dll" method. The URL I used was:
http://www.helloitsliam.com/_vti_bin/GetListXML.ashx?SiteUrl=http://www.helloitsliam.com&ListID={A462AB0D-84CF-4918-9950-D562530A5377}&ViewID={F10F58D9-716B-46EF-9FEF-E276A2B5EEF4}
This returned the following in the browser:
As you can see this method works really well and seems to work better than using the out of the box RPC Protocols.
Happy coding. J