I'm working on a POC for [a major national client] using the Business Data Catalogue feature for MOSS.  We are also developing a webservice from [a major enterprise CRM solution] (in .NET) to expose contract data that the client would like to have searchable from MOSS.  I haven't found too many resources to support BDC design and development, and much of what there is is fairly academic and works with communicating directly with databases rather than through webservices (except for this excellent one [1])  With some pain, I learned this one piece of design advice that I think is pretty important to share, especially since I have found more questions than answers in Googling my problems online.

 

Basically, the BDC is a connector that employs a Application Definition File (ADF) written in eXtesible Markup Language (XML), often employing some Single-Sign-On (SSO) authentication scheme, to request and return data from a remote source not directly associated with MOSS. 

 

While it is still early in my investigation, there is one important piece of information that should be considered in designing a webservice that is to be consumed by BDC.  System.Web.Services will automagically serialize typed objects to XML that will describe complete entities  as return objects from your webservice.  The mistake that we initiailly made in our quick and dirty first draft of the webservice was to retrieve the data we wanted from our legacy database, and then just stringbuild a response to be returned and express it with an XML content type.  This didn't work very well because the stringbuilder could be easily escaped and corrupted by concatenation of unusual characters or by URLencoding the "<" and ">" symbols that described our XML elements.  More imporrtantly, the SOAP envelope for our webservice methods declared that the response object would be XML, but gave no instructions on what the response object's schema would look like.  As an additional erroneous step, we instead tried to return an XmlDocument, which, while well-formed and far more reliable an approach to encoding XML, was still not illustrative of the contents that it was returning.  I first noticed this when I looked at the SOAP wrappers that present themselves when browsing the .ASMX:

 

 

HTTP/1.1 200 OK

Content-Type: text/xml; charset=utf-8

Content-Length: length

 

<?xml version="1.0" encoding="utf-8"?>

<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>

    <GetSomeListBySomethingResponse xmlns="http://www.mydomain.com/">

      <GetSomeListBySomethingResult>xml</GetSomeListBySomethingResult>

    </GetSomeListBySomethingResponse>

  </soap:Body>

</soap:Envelope>

 

 

Wow - you mean I'm sending you a request and you're going to send me a result of type "xml"?  Fantastic!  Well, not so much actually.  The real problem in my particular case was then when I employed the Business Data Catalogue Definition Utility (included with the SharePoint Server 2007 SDK [2]) to analyze the webservice, the return object, in my case, a collection of typed objects that I wanted to handle, was not recognizable as any kind of a "typed" object at all - all that I could reliably say about the response that it would be an XmlNode.

 

Properly speaking, I could probably have just manually constructed the entity definitions that I needed, but managing and maintaining these relationships would have been pretty tedious and using the tool allows one to manage schema changes quickly and to redeploy with a reduced amount of fuss.  I was hoping for that level of convenience and maintainability, rather than having to reconstruct all of the typing manually.

 

What makes this process much simpler (and perhaps what should have been made more explicit in some examples) is that in the webservice can return collections of class objects rather than XmlDocuments or strings.  So for example, if you have a webservice to fetch a customer record from a database, you would create a class file with all the declarations of the properties that make up a "customer" entity, and when you return your results, create a collection of customer entities (e.g. Customer[] customersToReturn = new Customer[upperbound]; ).  You can easily verify that your object typing is providing meaningful semantic information by re-checking the SOAP wrapper:

 

 

HTTP/1.1 200 OK

Content-Type: text/xml; charset=utf-8

Content-Length: length

 

<?xml version="1.0" encoding="utf-8"?>

<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>

    <GetSomeListBySomethingResponse xmlns="http://www.mydomain.com/">

      <GetSomeListBySomethingResult>

        <TheObjectIWant>

          <FirstProperty>string</FirstProperty>

          <SecondProperty>string</SecondProperty>

        </TheObjectIWant >

        <TheObjectIWant >

          <FirstProperty>string</FirstProperty>

          <SecondProperty>string</SecondProperty>

        </TheObjectIWant >

      </GetSomeListBySomethingResult >

    </GetSomeListBySomethingResponse >

  </soap:Body>

</soap:Envelope>

 

 

Notice that now, the typing that describes our entities is described in the envelope - handy, right?  The BDC Definition Utility will now properly parse the result as a typed object that will inform the BDC of the typing of your elements, and this will allow SharePoint to use or index or otherwise handle the responses from your legacy system without manual configuration.

 

So once you return properly typed XML-serialized values, the whole job or configuring your ADF becomes much less mysterious and frustrating.... but not completely so...  but that's for another blog post.

 

- g

 

[1] http://www.microsoft.com/downloads/details.aspx?FamilyID=6d94e307-67d9-41ac-b2d6-0074d6286fa9&DisplayLang=en

[2] http://blah.winsmarts.com/2007-4-SharePoint_2007__BDC_-_The_Business_Data_Catalog.aspx

Filed under: , ,