Search the articles  
  

• Collection Serialization ASP.NET Web Services

Tuesday, August 11, 2009

download : MembershipProvider Web Service Project with WSE(Web Service Security Enhancement)

After I have created a generic WSE MembershipProvider web service that can generally be used by membership registration pages, I checked the codes and compiled it. Everything looked fine but when I started making a web service call from client side, it run into the error: The type System.Collections.Hashtable is not supported because it implements IDictionary.

I just realized that data travelling across between web service call and web services must be in the form the serialized XML structure. In my web service case, I used Hashtable data type as a parameter at one of the web service methods. Obviously, Hashtable datatype can not be serialized because it is not a zero-based numeric collection unlike ArrayList that implement IList interface.

In fact, Hashtable data type is a key collection that implement IDictionary interface. It contains items that can be retrieved by an associated key value of some kind. The contents of IDictionary collections are also usually sorted in some fashion based on the key value and can be retrieved in sorted order by enumeration.

I have found a solution created by Mark Richman and I thought I should also share at my site.

Passing an IList
Collections that can be converted into single dimensional arrays can be passed directly in a Web Service. For
example, an ArrayList of type string serializes to the following XML:
<?xml version="1.0" encoding="utf-8" ?>
<ArrayOfAnyType xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <anyType xsi:type="xsd:string">MyString</anyType>
</ArrayOfAnyType>

Serializing an ArrayList referencing anything else than objects of type object raises an exception. That is the
reason for the restrictions on passing collections in the XML Serialization docs.

Passing an IDictionary as a Jagged Array
we can convert a name/value collection into a two column jagged array in which one column contains the key and the other contains the value. It’s pretty easy to write a two helper methods that convert between Hashtables and jagged arrays:

public object[][] ToJaggedArray(Hashtable ht)
{
   object[][] oo = new object[ht.Count][];
   int i = 0;
   foreach (object key in ht.Keys)
   {
      oo[i] = new object[]{key, ht[key]};
      i++;
   }
   return oo;
}

public Hashtable ToHashtable(object[][] oo)
{
   Hashtable ht = new Hashtable(oo.Length);
   foreach(object[] pair in oo)
   {
      object key = pair[0];
      object value = pair[1];
      ht[key] = value;
   }
   return ht;
}

To make use of these methods, simply change your WebMethod signatures from Hashtable/IDictionary to the jagged array. For example:

[WebMethod]
public Hashtable GetHashtable()

becomes:

[WebMethod]
public object[][] GetHashtable()

Serializing an IDictionary using XSD Types
we have exposed our WebMethods using types that can be serialized as XML, ASP.NET can
construct a proper SOAP envelope for our call:
<?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>
      <GetHashtableResponse xmlns="http://markrichman.com/webservices/">
         <GetHashtableResult>
            <ArrayOfAnyType>
                  <anyType/>
                  <anyType/>
            </ArrayOfAnyType>
            <ArrayOfAnyType>
                  <anyType/>
                  <anyType />
            </ArrayOfAnyType>
         </GetHashtableResult>
      </GetHashtableResponse>
   </soap:Body>
</soap:Envelope>
As you can see, the CLR object type is represented as the XSD type anyType.

The following codes are part of membership user create method for WSE MembershipProvider web service. You can also download the whole sample Visual Studio Project file at
download : MembershipProvider Web Service Project with WSE(Web Service Security Enhancement)



No comments:

Post a Comment