WebRequest (Follow up to HttpClient)

As a follow up to the previous post; We did find a limitation is our production environment that forced us to switch to a WebRequest instead of using the HttpClient. Given that this was the method we used to replace the functionality:

public XmlDocument SendServiceRequest(string uri, string xmlRequest)
{
    // Prep the request
    byte[] data = Encoding.ASCII.GetBytes(xmlRequest);
 
    // Create the HTTP request
    HttpWebRequest http = (HttpWebRequest) WebRequest.Create(uri);
    http.Method = "POST";
    http.ContentType = "application/xml";
    http.Accept = "application/xml";
    http.ContentLength = data.Length;
 
    // Place the xml into the stream
    using (Stream stream = http.GetRequestStream())
    {
        stream.Write(data, 0, data.Length);
    }
 
    // Get the response from the remote
    HttpWebResponse response = (HttpWebResponse) http.GetResponse();
 
    // Process the response stream if available. Create an empty XmlDocument if not
    XmlDocument xmlResponse = new XmlDocument();
 
    using (Stream responseStream = response.GetResponseStream())
    {
        if (responseStream != null)
        {
            using (StreamReader sr = new StreamReader(responseStream))
            {
                xmlResponse.LoadXml(sr.ReadToEnd());
            }
        }
    }
 
    return xmlResponse;
}

Using HttpClient for REST service calls

During a recent project we needed to make calls to a REST service out there on the net. I narrowed down the call to a basic method that I can call from other parts of my application.  This uses the HttpClient class and .Net 4.5

internal class RestHttpClient
{
    public async Task<HttpResponseMessage> SendRequestAsync(string uri, string xmlRequest)
    {
        using (HttpClient httpClient = new HttpClient())
        {
            StringContent httpContent = new StringContent(xmlRequest, Encoding.UTF8);
            HttpResponseMessage responseMessage;
            try
            {
                responseMessage = await httpClient.PostAsync(uri, httpContent);
            }
            catch (Exception ex)
            {
                responseMessage = new HttpResponseMessage
                {
                    StatusCode = HttpStatusCode.InternalServerError,
                    ReasonPhrase = string.Format("RestHttpClient.SendRequestAsync failed: {0}", ex)
                };
            }
 
            return responseMessage;
        }
    }
}

Elsewhere in the application this method is called as follows:

public async Task SendRequest(string uri, string xmlRequest)
{
    RestHttpClient restHttpClient = new RestHttpClient();
    return await restHttpClient.SendRequestAsync(uri, xmlRequest);
}

Rant: Microsoft Fakes

Ok, so I was really looking forward to the Fakes framework in VS 2012.  In the end a good portion of us are denied access to this feature because it’s only available in the Ultimate version of the product.

I guess the good thing is that Pex and Moles will still be viable.

Getting a list of domain group membership for a user account

I was looking for a way to get a list of a user’s associated domain groups. The first pass was to query AD using DirectorySearcher but the PrincipalContext was a less painful route to get what I needed. The method below will get the list of groups that the user belong to. Note that the user returned from the logonUserIdentity.Name will be in domain\user format. We split that apart so we can pass in the user part and also construct a domain.com string. That’s not the exact code I used since we have two different domains but it gets the idea across.

Update: I discovered that I needed to use the user name and password of a domain account for the PrincipalContext call. I installed the application on a virtual machine under IIS 7 and it was failing since the pool identity, NETWORKSERVICE, did not have rights to query AD. I ended up getting an exception:

DirectoryServicesCOMException (0x80072020): An operations error occurred

    public List<string> GetUserDomainGroups(WindowsIdentity logonUserIdentity)
    {
        List<string> groupList = new List<string>();

        string[] user = logonUserIdentity.Name.Split("\\".ToCharArray());
        user[0] += ".com";

        SecurityKey securityKey = GetSecurityKeyFromConfiguration();

        using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain, user[0], securityKey.UserName, securityKey.Password))
        {
            using (Principal principal = Principal.FindByIdentity(ctx, user[1]))
            {
                if (principal != null)
                {
                    PrincipalSearchResult<Principal> groups = principal.GetGroups();
                    using (groups)
                    {
                        groupList.AddRange(groups.Select(group => group.SamAccountName));
                    }
                }
            }
        }

        return groupList;
    }

Converting strings/byte arrays to encoded strings

I ran into this problem not to long ago where I needed to round trip strings between a coded format and their normal human readable format.

The basic idea was to take the string, and convert it to a byte array and then make a string representing the values in the byte array.  The resulting string would be used for a query string parameter and a few other things.

An example: If I have two words I would put a | between them.  hello there would be hello|there and the coded form would be 68656C6C6F7C7468657265

After a bit of digging I found a couple of threads on the net that gave me these two bits of code to go both directions.

string coded = new string(Encoding.UTF8.GetBytes(asciiString).SelectMany(x => x.ToString(“X2”).ToCharArray()).ToArray())

And to go back to the normal string

string notcoded = Encoding.UTF8.GetString(Enumerable.Range(0, hexString.Length / 2).Select(x => Byte.Parse(hexString.Substring(2 * x, 2), NumberStyles.HexNumber)).ToArray())

Not to bad at all with the LINQ in there, before that was around there were loops to get the whole thing done.

Beginners JQuery Video Series

I ran into a video tutorial for learning JQuery over at ThemeForest.net
I’m one of the people they talked about; I know its out there, I know it uses css selectors, and I know that it does a lot to hide some of the javascript pain. So I’m finally checking it out in more detail. Even though my preferred area is web services and other business layer on down I do still have to do some gui work from time to time.

WCF CreateChannel and no App.config

Alright; so I was working on a new project and I wanted to create a Windows Service that would host a WCF Service. The basic idea is that the Windows Service will use the WCF Service to do it’s heavy lifting on a schedule. The WCF Service will also be called from a management web site later on. In the past I’ve always wanted to reduce the amount of coding and configuration required to call one of these services.

So.. what did i come up with? The following lines create the service host in my Windows Service:

_wcfAsnService = new ServiceHost(typeof(Edi.Wcf.AsnService));
_wcfAsnService.AddServiceEndpoint(typeof(IAsnService), new NetTcpBinding(), Settings.Default.WcfAsnServer);
_wcfAsnService.Open();

The setting for that last parameter is defined as: net.tcp://localhost:8000

And I created this class to use for managing the life cycle of the client proxy:
using System;
using System.ServiceModel;
namespace EDI.AsnService

{
public class ServiceProxy : IDisposable
{

private readonly T _endPoint;
private readonly ICommunicationObject _proxy;

public ServiceProxy(string endPointAddress)

{
// Create a service client proxy
_endPoint = ChannelFactory.CreateChannel(new NetTcpBinding(), new EndpointAddress(endPointAddress));

// Create a CommunicationObject for state and end point closure
_proxy = _endPoint as ICommunicationObject;

}

public void Dispose()

{
// Close down the communication channel
if (_proxy != null)
_proxy.Close();
}

///
/// Returns the state object from the communication end point
///
public CommunicationState State
{
get { return _proxy.State; }
}

///

/// Returns the Endpoint where methods can be called

///

public T Client { get { return _endPoint; } }

}

}

Pretty simple. All you have to do is pass in the contract as the type and the proxy is created on the fly. Inside my method that executes the service client I have the following code to invoke the service:

using (ServiceProxy service = new ServiceProxy(Settings.Default.WcfAsnServer))
{

eventLog.WriteEntry(“Processing Start”);

eventLog.WriteEntry(service.Client.ExtractFromVisual().Message);

eventLog.WriteEntry(service.Client.UpdateGentran().Message);

eventLog.WriteEntry(“Processing Completed”);

}

The end result is that I don’t have to worry about configuring bindings in the config file. In fact the only thing I have in the config file in the endpoint address and port. I think this is much lighter weight and reduces some of the problems I’ve run into in the past with updating service references and duplication of the bindings in the config file.