WP7: Connecting to web services that uses authentication

No long valid, see here: https://zetitle.wordpress.com/2010/09/07/wp7-api-disappointment/

A little while ago, I was told by Microsoft that the current state of the WP7 API does not support header based authentication when dealing with web services. This put a lot of my work on hold since I do a lot of work with SharePoint and it’s web services.

For any that might be experiencing the same issues, here’s the exception I was getting:

unauthorizedexception

So, for the heck of it I wanted to see if this was true only for a small part of the API so instead of adding a service reference to the web service and letting Visual Studio generate the classes for me, I implemented a basic web service client on my own.

Turns out, this works 🙂

Here’s how I did it (Keep in mind, this is just a quick and dirty test and should be cleaned up before any production use):

First, we create the HttpWebRequest:

private static HttpWebRequest CreateWebRequest(string url, NetworkCredential credentials)
        {
            string action = "http://schemas.microsoft.com/sharepoint/soap/GetWebCollection";
            HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);
            req.Credentials = credentials;
            req.Headers["SOAPAction"] = action;
            req.ContentType = "text/xml;charset=\"utf-8\"";
            req.Accept = "text/xml";
            req.Method = "POST";
            return req;
        }

Then we create our SOAP envelope:

static string soapEnvelope = @"<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></soap:Body></soap:Envelope>";
private static XDocument CreateSoapEnvelope(string content)
{
    StringBuilder sb = new StringBuilder(soapEnvelope);
    sb.Insert(sb.ToString().IndexOf("</soap:Body>"), content);

    XDocument soapEnvelopeXml = XDocument.Parse(sb.ToString());

    return soapEnvelopeXml;
}

Now we insert the SOAP envelope into our web request:

private static void InsertSoapEnvelopeIntoWebRequest(XDocument soapEnvelopeXml, HttpWebRequest webRequest)
{
    webRequest.BeginGetRequestStream((IAsyncResult asynchronousResult) =>
    {
        HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
        Stream postStream = request.EndGetRequestStream(asynchronousResult);
        soapEnvelopeXml.Save(postStream);
        postStream.Close();

        request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
    }, webRequest);
}

And finally a method to handle the response:

private static void GetResponseCallback(IAsyncResult asynchronousResult)
{
    HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
    HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
    Stream streamResponse = response.GetResponseStream();
    StreamReader streamRead = new StreamReader(streamResponse);
    string responseString = streamRead.ReadToEnd();

    //do whatever with the response 

    streamResponse.Close();
    streamRead.Close();

    response.Close();
}

 

Ok, so now we have our methods – time to put them to use:

NetworkCredential credentials = new NetworkCredential("<user>", "<password>", "<domain>");
HttpWebRequest request = CreateWebRequest("<url>/_vti_bin/Webs.asmx", credentials);
XDocument soapEnvelope = CreateSoapEnvelope("<GetWebCollection xmlns=\"http://schemas.microsoft.com/sharepoint/soap/\" />");
InsertSoapEnvelopeIntoWebRequest(soapEnvelope, request);

And the result:

webssample fiddler

Windows Phone 7 and NTLM authentication

Well, it’s been confirmed: The current release of the WP7 API does NOT support NTLM authentication for web services. Perhaps at a later point before launch, but currently its a no go.

I was going to port my SharePoint Silverlight library to WP7 but it’ll have to be put on hold now as I can’t authenticate to SharePoint’s web services properly.

Still, there’s more fun to be had with WP7 even without this:)

Updated: There’s a workaround -> https://zetitle.wordpress.com/2010/03/30/wp7-connecting-to-web-services-that-uses-authentication/

Using SharePoint 2007 user profile service with Silverlight

When developing a Silverlight application that required the use of the user profile web service provided by SharePoint 2007, I discovered a rather frustrating bug.

Adding the service as a .NET 2.0 web reference, it will function as one would expect. However, when adding it as a service reference in a Silverlight project (as Silverlight has certain requirements of the web services it consumes) the bug kicks in.

It seems that the WSDL provides elements in the wrong order and also the autogenerated classes fails to handle objects of type like GUID (when calling methods they will fail stating that they don’t know how to handle the GUID values).

This only applies when reading data from the web service, when writing back it seems to function normally.

One solution I’ve found to work around this is to implement your own class for calling the web service and do the parsing yourself. I’ll probably do a post later on how I did this.