Recently, at the company I work for, I had to merge two very different web sites together. While both use C#, that is where they pretty much stopped in similarity. We were exploring ways to have them talk to one another very plainly and transmit only minimal amounts of data. One website was a store which was built around the idea of digital products and it had to talk to a portal we were creating to handle the subscription based products we were going to offer. Our solution needed to post data from one site to the other using formatted data that both systems understood.
I guess we could have made some remote connections but in this situation we knew a REST based API would be perfect for the situation. One site could fire off the request, the other handle it and send back a quick response. No fuss.
Once we chose this communication style we just needed to choose the way we were going to understand one another. We could have used something like JSON I suppose, but with a little handy XML serialization support already built into C#, it was just a matter of us defining some classes for packaging requests and we were off to the races.
The classes were half the battle and the other half was how to send this info between the sites. We created a typical WebRequest object and found that all we needed to do was set the content type of the request to “text/xml” and serialize it using an XMLSerializer. Then, when that was created, we quickly had the communication going. Below is a small example of how this could be done…
private Boolean PostObjectToURL(String url, Object obj) { WebRequest request = WebRequest.Create(url); request.ContentType = "text/xml"; request.Method = "POST"; Stream requestStream = request.GetRequestStream(); // Serializer using dynamic to get around compile time type checking Serializer<dynamic>.SerializeXmlObjectToStream(requestStream, obj); requestStream.Close(); using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { return (response.StatusCode == HttpStatusCode.OK); } }
This looks pretty standard but for one thing. Notice the use of dynamic here in the generic serializer type parameter. This is a feature from C# 4.0 onwards that will allow us to essentially pass any class, as an object, to the serializer and have it pass the compile time type checking. At runtime it will resolve the object type and make sure that our generic static functions will have the correct class types for serialization. The net result is that we can pass virtually any simple class to this function for serialization. In this example I simply return a Boolean to know if things were ok or not, but you could very well go into extensive try catch handling or returning multiple status codes etc if you need to.
To help facilitate the serialization and deserialization process, I created a generic static class that can essentially serialize objects (and deserialize) objects to the stream. In case you were wondering, it does this through class reflection. Below is the code for this and is used by the function above to serialize our incoming object on the request stream. This tidbit is great for your library if you don’t already have something similar.
public class Serializer<T> { public static void SerializeXmlObjectToStream(Stream stream, T theObject) { XmlSerializer serial = new XmlSerializer(theObject.GetType()); serial.Serialize(stream, theObject); } public static T XmlStreamToObject(Stream XmlStream) { XmlSerializer serial = new XmlSerializer(typeof(T)); return (T) serial.Deserialize(XmlStream); } public static T XmlStringToObject(String XmlString) { XmlSerializer serial = new XmlSerializer(typeof(T)); return (T)serial.Deserialize(new StringReader(XmlString)); } }
So let’s assume I want to post some class to a specific endpoint URL to ask the other site if a subscription exists for the given user and product. Here is what that class could look like…
[XmlRoot("subscriptionExists")] public class SubscriptionExistsRequest { [XmlElement("UserID")] public int UserID { get; set; } [XmlElement("Username")] public String Username { get; set; } [XmlElement("ProductID")] public int ProductID { get; set; } }
We could then create an instance of this class, set its properties and then throw it over to the PostObjectToURL() function, along with the URL endpoint of our destination API, and it will serialize it as an XML POST request. On the flip side the other site can then receive the post request, deserialize it (using the same Serializer
SubscriptionExistsRequest existRequest = new SubscriptionExistsRequest(); existRequest.UserID = 2; existRequest.Username = “some@email.com”; existRequest.ProductID = 3783; PostObjectToURL(“http://www.mysite.com/Subscriptions”, existRequest);
Once we had this going, we wanted to make sure that we could see how our requests were coming along and if there were any issues. Being someone who does a bit of PHP as well, I simply fired up the local webserver, created a page that did a file_get_contents(“php://input”) and wrote it to file. Then you can post from your C# project locally to the PHP file and see the result in the text file. Worked out nicely and got things moving along well.
After all this, we were working with subscriptions and having our two sites talk to one another seamlessly. Now only if we can get management to make up their minds as to what they really want these sites to do. Thanks for reading!