Click here to Skip to main content
Click here to Skip to main content

HTTP Binary Serialization through ASP.NET without WCF

By , 15 Aug 2009
 

Introduction

While developing client/server applications, you often need to send an object to your client. The easiest way for us programmers to work with an object would be to get the whole object from the server, not just some properties.

One way to do this is to use WCF or Web Services, which give you a whole set of tools, like serialization to accomplish this task, but these set of technologies often bring a lot of overhead and complexities to your project, that often you would not want if what you're doing is just sending and receiving one or more objects.

Faced with this dilemma, I spent some time looking for a solution to this; my goal was to find a very easy, simple, and clean way to create an object on the server, serialize it, and send it back to the client. Security and interoperability were not a concern at this point, but they could be implemented later. The constraints for this were that it had to be fast and it had to work through the basic HTTP protocol.

My solution was to create an ASP.NET page that reads the query string to determine what object to return, creates the object, serializes it to binary, and returns it as a binary attachment to the client. The client downloads this file using the WebClient() class and deserializes it back to the object.

Both the server and the client share a class library containing the common object. At first, I implemented this using XML serialization, but found that it is quite slow, but it could also be used if you require interoperability.

Background

Bear in mind that this is not the only way to do this; you probably can do it with WCF using a custom binding or using MTOM, but I found in my experience that these methods were too involved and added unnecessary complexity for simple projects.

Using the Code

On the web server page load, we include code to check which object the client is requesting, and return the serialized object as a binary attachment.

protected void Page_Load(object sender, EventArgs e)
{
    // Check which object the client wants
    if (Request.QueryString["op"] == "getdata")
    {
        // Create a new instance of the sample data object
        var data = new SampleData();
        data.moreData = 34343;
        data.otherData = true;
        data.SomeData = "fewoifjweofjwepo";
        // Set content type and header
        // octet-stream allow us to send binary data
        // the file name here is irrelevant as it is 
        // not actually used by the client.
        Response.ContentType = "application/octet-stream";
        Response.AppendHeader("Content-Disposition", 
                             "attachment; filename=sampleData.bin");
        // Serialzie the object and write it to the response stream
        var binaryFormatter = new BinaryFormatter();
        binaryFormatter.Serialize(Response.OutputStream, data);
        // Its important to end the response, overwise the other page content
        // would be sent to the client.
        Response.End();
    }

On the client, we create the request to the server using a query string, and deserialize the response.

// Create the url for the service, this could be stored in a configuration file
string url = "http://localhost/BinaryServiceSample/Default.aspx?op=getdata";
// Download the data to a byte array
// This data contains the actual object
var client = new WebClient();
byte[] result = client.DownloadData(url);
// Create a memory stream to stored the object
var mem = new MemoryStream(result);
var binaryFormatter = new BinaryFormatter();
var data = (SampleData)binaryFormatter.Deserialize(mem);
mem.Close();
// Write object to the console
Console.Write(data.ToString());
Console.ReadLine();

Points of Interest

  • Although binary serialization may "feel" more comfortable, it may not be compatible across different platforms.
  • Serializing objects using binary serialization is way faster than XML.
  • This code does not include any error handling, this is something that could be easily incorporated into it. I did not include it to make it more clear and simple.
  • One way to add security is to encrypt the actual bytes before sending them to the client; this, of course, would make interoperability very difficult.
  • Additional transport speed could be obtained by compressing the bytes before sending them; I know ICSharpCode.SharpZipLib.dll can compress in memory bytes, and it is free, but you could also do it with the .NET Framework by implementing HTTP compression and embedding it into your code - check out this article for an example: http://www.codeproject.com/Articles/38067/Compress-Response.aspx.
  • Serializing an object like this seems to give me more control over how things are done without adding too much complexity.

I would like to receive comments, suggestions, and constructive criticism about this, if you have any, or any improvements, please let me know so I can include them.

Thanks to Andre Sanches for his contributions to this article.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Ricardo Pineda
Software Developer NeoDeck Software
Puerto Rico Puerto Rico
Member
I've been programming since I was 10 years old, and I consider it my passion. I founded NeoDeck Software a small development company in 2002, and we've been in business developing various applications, concentrating in medical software.
 
My programming experience ranges from VB6, C#, VB.NET and Objective-C.
I have experience in SQL Server, ASP.NET, WCF, WPF, Blend, Silverlight, SQLite, iPhone and XCode.
 
I'm a Microsoft Certified Professional and have a Bachelors Degree in Computer Science.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5membermanoj kumar choubey16 Apr '12 - 3:28 
Nice
GeneralMy vote of 5memberKanasz Robert12 Nov '10 - 0:30 
Good job man.
GeneralThanksmemberlilzi3 Nov '09 - 20:19 
I've already submitted a project that supports Json serialization(Session, cookie, query string & cache variables unified [^]). This article will help me implement binary serialization in it as well. CheersThumbs Up | :thumbsup:
GeneralSuggestionmemberjackmos19 Aug '09 - 2:56 
You got my 5 for getting right to the point and providing a practical, easily implemented and tight solution.
But, I'd suggest you implement this as an HttpHandler to reduce the overhead. Doesn't change the intent or the code (much), but makes it cleaner.
GeneralRe: SuggestionmemberRicardo Pineda24 Aug '09 - 12:18 
Hi, thanks for your suggestion!, can you provide a sample of how you would use HttpHandler in the code?
GeneralRe: Suggestionmemberjackmos24 Aug '09 - 12:34 
Here's a sample from another project that returns the contents of a file using an HttpHandler:
 
using System;
using System.IO;
using System.Web;
 
namespace Lib2 {
 
	public class DownloadFileHandler : IHttpHandler {
 
		public bool IsReusable {
			get { return (false); }
		}
 
		public void ProcessRequest(HttpContext ctx) {
			string fName = ctx.Request["fn"] ?? string.Empty;
			string fPath = Path.Combine(ctx.Server.MapPath("~/Downloads2"), fName);
			try {
				ctx.Response.Cache.SetCacheability(HttpCacheability.NoCache);
				ctx.Response.ContentType = "application/octet-stream";
				if (File.Exists(fPath)) {
					ctx.Response.WriteFile(fPath);
				}
			} catch (Exception ee) {
				string msg = ee.Message;
			}
		}
	}
}
 
 
Note that you'll have to register this in the web.config file as:
 
<httpHandlers>			
		<add verb="*" path="DownloadFileHandler*.aspx" type="Lib2.DownloadFileHandler, Lib2"/>			
</httpHandlers>
 
There are lots of examples on the web. Try Google for more info.
GeneralMy 2 centsmemberAndre Luiz V Sanches13 Aug '09 - 12:18 
Great article, two suggestions to improve it:
 
1) You should mention that although binary serialization may "feel" more comfortable, it may not be compatible across different platforms
 
2) You mentioned some external tools/modules to compress the http output, but you can easily implement HTTP compression using the namespaces that are built into .NET and embed it into your code - check out this article for an example: http://www.codeproject.com/Articles/38067/Compress-Response.aspx[^]
 
---------
Andre Sanches
 
"UNIX is friendly, it's just picky about its friends"

GeneralRe: My 2 centsmemberRicardo Pineda14 Aug '09 - 11:08 
Thanks for the info! I just sent an update to the article to include this.
 
I didn't know about that compression-response, nice!
 
Cheers
Question17 and have bachelor degree?memberAndre Luiz V Sanches12 Aug '09 - 12:09 
Seriously?
 
---------
Andre Sanches
 
"UNIX is friendly, it's just picky about its friends"

AnswerRe: 17 and have bachelor degree?memberRicardo Pineda13 Aug '09 - 11:12 
Andre Luiz V Sanches wrote:
Seriously?

 
Sorry about that, I meant to say 17 years programming, not that I'm 17. Althought there must be some kids with those qualifications, I'm not one! I'm actually 27, I finished the BS when I was 24.
 
Cheers
GeneralRe: 17 and have bachelor degree?memberAndre Luiz V Sanches13 Aug '09 - 12:00 
I guess you deserve a 5 for answering so politely to a totally off-topic and unnecessary question Smile | :)
 
To make up for it I added a separate comment with actual constructive stuff.
 
---------
Andre Sanches
 
"UNIX is friendly, it's just picky about its friends"

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130516.1 | Last Updated 15 Aug 2009
Article Copyright 2009 by Ricardo Pineda
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid