Blog

  • Frustrating Cookies

    Tags: asp.net, cookie

    On a recent project, I encountered a very frustrating issue with browser cookies.

    The server was sending a cookie to the browser. The user should then be able to remove the cookie using JavaScript.

    this.Response.Cookies.Add(new HttpCookie("Funky:Name", "SomeValue"));

    The initial approach was using a very simple home cooked method for setting the expiration date on the cookie. The standard way for removing a cookie is to set the expiration date to some time in the past.

    Just a note, the native cookie api in modern browsers is flat out ridiculous! You have to manipulate a string which contains all available cookies - no separate methods for creation, update or deletion.

    The approach was working fine in Internet Explorer, but for some reason the JavaScript was unable to remove the cookie when running in Chrome. I tried swapping out the home cooked code for the jQuere cookie plugin. No change, the cookie was stuck.

    I then tried to create the cookie using the jQuery cookie plugin instead, and see if this cookie could be removed. Now for an interesting observation. For some reason the name of the cookie in question was something like "Funky:Name".

    When viewing the current cookies in the Chrome debugger, the cookie set by the server would show up with the name "Funky:Name". However, the cookie set by the jQuery pugin would show up as "Funky%3AName". Clearly the name had been encoded. It turns out, that the jQuiery plugin is using the native javascript encodeURIComponent method to encode the name of the cookie.

    Which is correct, Internet Explorer or Chrome? In any case, the Chrome behavior of accepting the un-encoded name sent by the web server and then not being able to modify must be wrong. There is a good answer on StackOverflow on which characters are allowed for cookie names. It seems that the character ":" is in fact not allowed.

    Given the disallowed character, I would say that Internet Explorer, Chrome and ASP.NET are all incorrect in their implementation. Internet Explorer supports the standard (but with additions), Chrome is a bit twisted as it adheres to the standard sometime and not others.

    If names must be encoded, the ASP.NET code should be updated to encode the name when sent to the browser. UrlEncode method of the HttpUtility class to encode your cookie names when creating them on the server.

    NOTE that the http specification specifies that a cookie sent from a server may set a flag (HttpOnly) to indicate that the cookie is only accessible by the server, not the clientside javascript. This was not the issue in this case.

  • Contravariance and Covariance in C#

    Tags: Contravariance, Covariance, c#, generics

    It is a general feature of object that we can supply a more specialized type to a method parameter if the supplied type inherits from the required type.

    Likewise, we can capture an object reference using a weaker type than the actual object.

    public void Test()inheritance
    {
       
    // Call method with more specialized argument
       
    this.Method(new LevelTwo());

       
    // Hold variable reference with weaker type
       
    LevelOne a = new LevelTwo();
    }

    public void Method(LevelOne param)
    {
        ...
    }

    This is all well know and indeed useful. C# extends this principle for generics.

    We can reference a class implementing a generic interface using a weaker generic parameter if the interface only use the generic parameter type as return types. This is known as Covariance, and must be specified on the interface using the out keyword. This is directly comparable to capturing an object reference with a weaker type.

    public interface IContravariance<in T>
    {
      
    void Method(T input);
    }

    public class Contravariance<T> : IContravariance<T> { ... }

    // Reference a class using a stronger generic type parameter.
    IContravariance<LevelThree> b = new Contravariance<LevelTwo>(); 

    If the interface is only using the generic type for method arguments, we can reference the type using the interface with a more specialized type if the interface is only using the generic type parameter for method arguments. This is known as Contravariance, and must be speficied on the interface using the in keywork. This is directly comparable to calling a method with a more specialized type.

    public interface ICovariance<out T>
    {
       T Method();
    }

    public class Covariance<T> : ICovariance<T> { ... }

    // Reference a class using a weaking generic paramter.
    ICovariance<LevelOne> a = new Covariance<LevelTwo>(); 

    You will not get this functionality for free. C# requires you to explicitly specify, that you will only use a generic parameter as either out or in. If nothing is specified, no variance is allowed.

    The BCL is doing this all over the place. You should too in your project, but bear in mind that once a library with such a declaration is released, it will be a breaking change to alter it.

  • Drawing Partial Circles with ArcSegment

    Tags: windows phone, partial circle, ui, path, wpf, silverlight

    Silverlight and WPF provides the ArcSegment class for drawing arcs. However, it is meant for use as part of a Path, which makes it a bit difficult to use for drawing partial circles. When used as part of a path, the starting point of the arc is set on the parent figure, and the ArcSegment itself only defines an end point and a size. The following sample code draws half a circle, with radius 50 starting from (0, 50) and ending in (100, 50).

    <Path Stroke="Orange" StrokeThickness="10">
      <Path.Data>
        <PathGeometry>
         
    <PathFigure StartPoint="0, 50"
           
    <ArcSegment Point="100, 50" Size="50, 50"></ArcSegment>
         
    </PathFigure>
       
    </PathGeometry>
      
    </Path.Data>
    </Path>

    In order to draw a partial circle, we need to calculate the ending point of the circle. Intuitively the 25%, 50% and 75% coordinates are easily found. It is simply a matter of working with the radius.

    The peripheral coordinates of a circle are given by:

    X: center.x + radius * cos(deg)
    Y: center.y + radius * sin(deg)

    Where deg is the degrees in radians.

    This is basic math, but little mistakes here make for quite frustrating issues.

     

    What we really want is a control, which takes a size and a percentage of a circle, and draws this as a partial circle.

    <phoneApp1:PartialCircle Percentage="62" Radius="200" />

    Click here to download the sample code implementing a simple user control providing this functionality.

    NOTE Given the nature of a path, you may experience the path being rendered outside the bounds of the parent container. To fix this, you can subtract half the thickness of the circle stroke from the radius of the circle.