Ed Giardina's .NET Blog

Blogging about Hobbyist Adventures in C#, XNA, ASP.NET and other stuff

January 2010 - Posts

Back in the .NET Game; Plus

So I took a new job which has me writing C# code again, which is great! A lot of new developments have happened in ASP.NET land since I've been gone, such as MVC framework, ASP.NET 3.5, etc. However, I've been working to keep up with them and I'm excited about what the future holds.

The last few days I've been working on a Flex + Sharepoint project for my employer. Sharepoint has a robust set of web services, but accessing them can be a bit confusing. For the method 'GetListItems', accessing all items from a list can be pretty easy... the http://sharepointserver/_vti_bin/Lists.asmx service endpoint provides you with the ability to getListItems by listName ...however, if you want to do more than just grab one list item, you might be in for a hurting. Getting a specific subset of lists means you have to pass in a complex parameter, like viewFields ... The viewFields parameter of GetListItems is not a simple type like a string or number. Instead, its an XML subtype and you're required to pass in a specific format of XML within this node. If you pass XML that sharepoint does not expect, you'll see something like ' ViewFields is missing or invalid' ... Normally people consume web services with generated code from ASP.NET... When I found myself in Flex, however, the generated tools fell a little short.

Problem 1 is that Flex WebServices libraries by default append a namespace to each node that they send in their Soap Bodies. Usually the namespace is "tns:" ... that's fine, but it was unclear to me if the complex XML children parameters of the webservice needed this namespace too... turns out, they do not.

<soap-env:envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soap-env:body>
    <tns:getlistitems xmlns:tns="http://schemas.microsoft.com/sharepoint/soap/">
      <tns:listname>Regions</tns:listname>
      <tns:viewfields>
        <viewfields>
          <fieldref name="LinkTitle">
        </fieldref>
      </viewfields>
      <tns:rowlimit>2</tns:rowlimit>
      <tns:queryoptions>
        <queryoptions>
          <includemandatorycolumns>FALSE</includemandatorycolumns>
          <dateinutc>TRUE</dateinutc>
        </queryoptions>
      </tns:queryoptions>
    </tns:viewfields>
  </tns:getlistitems>
</soap-env:body></soap-env:envelope>

(note the lack of 'tns:' in the 'queryoptions' and 'viewfields' parameters)

Problem 2 is lack of examples of actual web requests of Sharepoint services. Which normally you wouldn't need if you're consuming generated code from Visual Studio. But if you're writing custom webservice wrappers, or doing anything nonstandard, then you need to have your hands dirty and understand what's going on at the transport level. For a while I didn't realize that the viewFields parameter needed , as its root child element, a viewFields element... the examples page was unclear; and every other code example had me writing ASP,NET go-between layers. That's not what I want, I want my Flex movie talking right to sharepoint. Anyways, what made this whole process way easier was Flash Builder 4, which generates code for you based on a WSDL; a lot like ASP.NET does. So you end up with something like this:

 

var viewFields:XML = <ViewFields><FieldRef Name="LinkTitle" /></ViewFields>;
 var queryOptions:XML =
                    <QueryOptions>
                       <IncludeMandatoryColumns>FALSE
                          </IncludeMandatoryColumns>
                       <DateInUtc>TRUE</DateInUtc>
                    </QueryOptions>;
           
var myLists:Lists = new Lists();
                               
myLists.addEventListener(FaultEvent.FAULT, handleFaults);
myLists.addEventListener(ResultEvent.RESULT, RegionsResult);
myLists.GetListItems("Regions",null, null, viewFields, "2", queryOptions, null);

Makes sense now, but if you're coming in green, Sharepoint connectivity can be a pain without raw XML examples!