Compress/Decompress a String in C#

December 26, 2012 Leave a comment

The feature I was working on today involved saving some temporary data into an HTTP session cookie. The data was an object serialized into JSON. Writing and reading cookies is easy enough but, after testing my implementation a bit, I found out that my code was intermittently failing to save the cookie in my browser. After some deeper investigation, I found that the reason my cookie wasn’t being saved (sometimes) was because the JSON I was attempting to store in the cookie was exceeding the 4K limit of a cookie. The object I was serializing to JSON was a List of other classes so I could not prevent users from exceeding the limit without imposing arbitrary restrictions on the usage of the feature. I also wanted to keep the data on the client’s machine, as opposed to a DB or other storage medium, because the data really did seem to belong in the user’s session. The only option I could think of to solve my problem was to compress the JSON string.

Unfortunately, when I Google’d “C# compress string” (or something like that), the results weren’t very helpful. Most of the code I came across was either for .NET 2.0 or was doing File IO and byte array manipulation with pointers. Many examples didn’t even make proper usage of using() blocks to properly close Streams. What I needed was .NET 4.0 code to Compress and Decompress strings to strings, preferably without needing to do any byte pointer magic. Fortunately, I eventually came across this some-what helpful Stack Overflow Q&A which was close enough to what I was trying to do. The OP was looking for a .NET 2.0 solution and his compressed medium was a byte[] instead of a string but, with a few simple modifications, I was able to adapt the code to do exactly what I needed.

using System;
using System.IO;
using System.IO.Compression;
using System.Text;

...

public static string Compress(string s)
{
    var bytes = Encoding.Unicode.GetBytes(s);
    using (var msi = new MemoryStream(bytes))
    using (var mso = new MemoryStream())
    {
        using (var gs = new GZipStream(mso, CompressionMode.Compress))
        {
            msi.CopyTo(gs);
        }
        return Convert.ToBase64String(mso.ToArray());
    }
}

public static string Decompress(string s)
{
    var bytes = Convert.FromBase64String(s);
    using (var msi = new MemoryStream(bytes))
    using (var mso = new MemoryStream())
    {
        using (var gs = new GZipStream(msi, CompressionMode.Decompress))
        {
            gs.CopyTo(mso);
        }
        return Encoding.Unicode.GetString(mso.ToArray());
    }
}

It is simple, elegant, and best-of-all… it works! Luckily for me, JSON compresses extremely well. The previous data which was failing to save was about 4.5 K but I was able to reduce that down to only 1.5 K after compression! The only drawback I have noticed so far of storing compressed data in a cookie is that it is not human readable. You could spin that as a good thing because users will be less likely to want to see/modify obfuscated cookie values, but as a web-developer, I usually like knowing exactly what is being stored on my computer by the websites I visit. An (unintentional) positive side-effect of compressing the cookie is that it helps minimize the amount of data being sent back-and-forth from the users and our servers. 4K might not seem like a lot of data, but when it is being sent in every request from the user’s browser, it can add up. Either way, this simple code helped me solve this problem… moving on!

ASP.NET Data-Bind tag vs. Evaluation tag ‘Gotcha’

August 2, 2012 Leave a comment

My team ran into an interesting problem today while trying to fix a NullReferenceException from within an ASPX page. We had the following (simplified) code in the page:

<span>MyString # of characters: <%# MyString.Length %></span>

Of coarse, when MyString was null, this page was throwing the NullReferenceException. To solve this, we added a null check around the whole block.

<% if (MyString != null) { %>
    <span>MyString # of characters: <%# MyString.Length %></span>
<% } %>

By making this change, our understanding was that the inner block should not be evaluated by the server because of the conditional check around it. We tested this out with the case where MyString was null. To our surprise, we still got a NullReferenceException but this time with more details. The stack trace eluded tho the problem stemming from a DataBind() invocation.

The problem with this code is that we are attempting to use a DataBind expression in our ASPX page. DataBind constructs (<%# %>) get evaluated by the DataBind() method regardless of what conditional constructs surround them in the page. This mistake was simply caused by our inexperience ASP.

The solution was to switch the DataBind expression to, what I will call, an Evaluation expression. These expressions are the ones with the <%= %> syntax. I call them “evaluation” expressions because the documentation doesn’t refer to them as anything other than “the <%= %> construct”. They don’t use the DataBind functionality at all. Instead they are the equivalent of calling Response.Write() from within your page; they output the result of the expression as plan text into your markup. Our working solution looks like this:

<% if (MyString != null) { %>
    <span>MyString # of characters: <%= MyString.Length %></span>
<% } %>

A more seasoned ASP.NET developer may have thought “Duh, don’t do that” but it may not be so obvious to others. Unfortunately, I have seen DataBind and Evaluation expressions used almost interchangeably in many applications. They have different purposes and the differences between them need to be understood to be effective in ASP.NET. To learn these differences and understand when to use one vs. the other, I found the following resources helpful.

What are these special tags: <%# and <%= (Microsoft ASP.NET Forums)

ASP.NET Databinding/Server tags differences, declarative output property? (StackOverflow)

Hiring Web Designers!

February 23, 2012 Leave a comment

At Point2, we love doing what we do best  — creating compelling, innovative software.  Do you eat, sleep, and breathe web design? If you are a passionate Web Designer looking for exciting new and interesting challenges, we would love to hear from you!

The ideal candidate for this position will not only possess an experienced approach to design, but will also mesh seamlessly with the rest of our team of web designers and developers. In this role, you will collaborate with designers and developers to help create cutting-edge web experiences for our customers. You will also work closely with many other business units within Point2 in order to help expand our new product lines and maintain our various web-based products.

We are looking for someone who has:

- Extensive experience developing consumer and/or commercial websites
– Ability to create great looking intuitive user experiences

- 3-5 years demonstrated experience hand-coding advanced HTML, CSS, and Javascript
– Proficiency using the Adobe Creative Suite, including Photoshop, Fireworks, and Illustrator
– Ability to design, code, and troubleshoot for all major browsers
– Awareness of the latest design & development trends and technologies
– Experience working into a highly-collaborative team environment
– Bachelor’s Degree or certificate in web/graphic design or equivalent (preferred)

- Experience with jQuery and mobile web design (an asset)

Interested in joining the team? Email your resume to WEBDEVcareers@point2.com  or apply online http://www.point2.com/applyonline. Include samples of your work with your application.

Point2, a division of Yardi Systems, offers competitive salaries, comprehensive benefits, and professional development opportunities.

Join the vibrant team in Saskatoon, SK and enjoy living in place that blends small town appeal with big city amenities.  If you drop by our office, you will notice:

  • Plenty of laughter mixed with a serious drive to be the very best
  • Gourmet coffee and fresh fruit daily
  • Blue jeans, lava lamps, and family photos
  • Foosball, pool tables, and comfy couches
  • Yoga mats, fitness balls, free weights
  • Whiteboards … everywhere
Categories: Point2 - Technical

Hiring Software Developers!

February 23, 2012 Leave a comment

Agile, XP, and DevOps. Innovation, creativity, and excitement. Buzzwords? Maybe they are, but we don’t care what you call it. We want to get stuff done. You want to get stuff done? Come and collaborate with our team, so we can get stuff done.

We are developing a suite of new and exciting products. Our base toolkit includes Python, Scala, C#, MongoDB, .Net MVC, Java, MSSQL, ActiveMQ, VMWare, SVN, and Git. More buzzwords? Maybe, but we still don’t care what you call it. You don’t have to search in the deepest and darkest corners of our basement to find these technologies. We use them daily, and we work them hard.

We’ve got lots of exciting projects to do. We want to get them done because winners lead, and we want to be out front. We want to add more awesome people to the group of smart and talented people we already have. We want people that can hit the ground running. We want people that can bring their game and own this job.

You better like having passionate discussions. You better not hold back (because we don’t). You better want to learn and teach something every day. You better deliver value because you write wicked awesome code. What? That’s you?  Then you better apply for this job because WE WANT YOU!

Show us what you’ve got. Email your resume to IveGotWhatItTakes@point2.com or apply online http://www.point2.com/applyonline.

Point2, a division of Yardi Systems, offers competitive salaries, comprehensive benefits, and professional development opportunities. You’ll be working in Saskatoon. The office has lots of geek stuff like fresh ground coffee, foosball, pool tables, and whiteboards. It’s awesome.

Categories: Point2 - Technical

February 3, 2012 Leave a comment

In one of the MVC3 apps i’ve been working on we decided to make sure that all of the urls specify information in a restful fashion, that is they are all directly in the path(route), nothing in request parameters.  Everything was going smoothly until we hit our first action where parameters are optional.

Lets look at this theoretical route table:

"{controller}/{action}/{year}/team/{teamId}/car/{carId}/track/{trackId}"
"{controller}/{action}/{year}/track/{trackId}/car/{carId}"
"{controller}/{action}/{year}/car/{carId}"

So you could imagine that we would have different urls that apply to these routes like:

http://www.racingstats.com/yearlySummary/Nascar/2011/team/AmsOil/car/12 
http://www.racingstats.com/yearlySummary/Nascar/2011/track/taladega/car/12 
http://www.racingstats.com/yearlySummary/Nascar/2011/car/12 

The problem is that this url pattern isn’t gracefully handled out of the box with mvc3.  If you tried to hit one you would be greated with a nice exception:

The current request for action ‘Nascar’ on controller type ‘YearlySummaryController’ is ambiguous between the following action methods:….

see the solution here…

 

YAGNI Doesn’t Always Apply

January 18, 2012 Leave a comment

YAGNI means You Aren’t Going to Need It. It’s a software development philosophy that suggests features should not be added until a customer (or product owner) asks for them. Many times, you really aren’t going to need it, but if you apply YAGNI incorrectly you may get yourself into a bit of trouble and your code may begin to smell

Read More

 

Removing empty XML elements in Scala

March 21, 2011 1 comment
import xml.transform.{RuleTransformer, RewriteRule}
import xml.{NodeSeq, Node, Elem}
import xml.Utility.trim

object RemoveEmptyElementsSpike {
  val x1 = <xml><empty/><nonEmpty>data</nonEmpty></xml>
  val x2 = <xml><nonEmpty name="legend"></nonEmpty><empty /></xml>
  val x3 = <xml><Empty><empty/></Empty><nonEmpty>data</nonEmpty></xml>
  val x4 = <xml><empty>
           </empty><nonEmpty>data</nonEmpty></xml>
  val x5 = <xml><empty c={val s:String=null;s}/><nonEmpty name="f"/></xml>

  class RemoveEmptyTagsRule extends RewriteRule {
      override def transform(n: Node) = n match {
          case e @ Elem(prefix, label, attributes, scope, child @ _*) if
              (isEmptyElement(e)) => NodeSeq.Empty
          case other => other
      }
  }

  val myRule = new RuleTransformer(new RemoveEmptyTagsRule)

  private def isEmptyElement(n: Node): Boolean = n match {
      case e @ Elem(prefix, label, attributes, scope, child @ _*) if
          (e.text.isEmpty &&
            (e.attributes.isEmpty || e.attributes.forall(_.value == null))
           && e.child.isEmpty) => true
      case other => false
  }

  def main(args: Array[String]) = {
      println(myRule.transform(trim(x1)))
      println(myRule.transform(trim(x2)))
      println(myRule.transform(trim(x3)))
      println(myRule.transform(trim(x4)))
      println(myRule.transform(trim(x5)))
  }
}

/* Output
<xml><nonEmpty>data</nonEmpty></xml>
<xml><nonEmpty name="legend"></nonEmpty></xml>
<xml><nonEmpty>data</nonEmpty></xml>
<xml><nonEmpty>data</nonEmpty></xml>
<xml><nonEmpty name="f"></nonEmpty></xml>
*/
Follow

Get every new post delivered to your Inbox.