ASP.Net MVC 1.0 has been released!

by cweiss 18. March 2009 08:14

The months of waiting are over! ASP.Net MVC 1.0 has finally been released. Get it while it's HOT!!

http://www.microsoft.com/downloads/details.aspx?FamilyID=53289097-73ce-43bf-b6a6-35e00103cb4b&displaylang=en

Tags:

Meet me @ BASTA! Spring 2009

by cweiss 20. February 2009 13:21

Hello everyone!

Next week, I will attend the biggest German .NET conference “BASTA! Spring 2009”. Feel free to contact me, if you’d like to chat with me “offline” there!

What’s next on my blog?

I’m working on an ASP.Net MVC application right now and I plan to post about some of the techniques I’ve used, so expect to read from me after the conference!

Thanks for reading,
Christian Weiss

Tags:

Personal

Testable and reusable cookie access with ASP.Net MVC RC

by cweiss 28. January 2009 18:35

All good things come in threes, so I’m writing another post about how to access cookie or sessions. I got inspired by a comment from Chris Marisic, who suggested to use a more testable way for this stuff!

Previous posts about this topic:

Intro

Using static wrapper properties is a quick and easy way, but you can’t unit test them because they access HttpContext.Current directly. This time I will show you, how you can build a fully unit testable and strongly typed way to access your cookies. As there has been Christmas time 2 days ago (ASP.Net MVC RC1 was released *g*) I’m using the latest MVC bits for my example!

A Reusable Cookie Container

The cookie container is responsible for getting values out of and into the cookie collections. It does not know which concrete values I’m using in my application! This is implemented in a different level, so you can use this class for all of your applications!

In my implementation it’s possible to store “objects” in cookies. I’ve implemented it this way because I don’t want to convert all my DateTime, int, … cookies every time! But I also don’t want someone to save Lists or any other complex types, so my SetValue() method validates the type of the value and throws an exception, if it’s not a value type or nullable value type. That’s a little type checking, but I think it is worth it because cookies are set quite rarely!

Here’s the interface:

public interface ICookieContainer
{
    bool Exists(string key);
    
    string GetValue(string key);
    T GetValue<T>(string key);
    
    void SetValue(string key, object value, DateTime expires);
}

I will just show the fundamental code here. If you want to see the whole implementation, please take a look at the code sample. (see bottom)

As you can see below, I’ve used the abstracted versions of HttpRequest and HttpResponse, which you get, if you use ASP.Net MVC. That’s just one of thousand things I love about ASP.Net MVC. These classes can be used easily in unit tests. Notice that everything can be injected here. There’s no direct access to HttpContext.Current!

public class CookieContainer : ICookieContainer
{
    private readonly HttpRequestBase _request;
    private readonly HttpResponseBase _response;

    public CookieContainer(HttpRequestBase request, HttpResponseBase response)
    {
        // "Check" is a helper class, I've got from the "Kigg" project
        Check.IsNotNull(request, "request");
        Check.IsNotNull(response, "response");

        _request = request;
        _response = response;
    }

    public string GetValue(string key)
    {
        Check.IsNotEmpty(key, "key");

        HttpCookie cookie = _request.Cookies[key];
        return cookie != null ? cookie.Value : null;
    }

    public void SetValue(string key, object value, DateTime expires)
    {
        Check.IsNotEmpty(key, "key");

        string strValue = CheckAndConvertValue(value);

        HttpCookie cookie = new HttpCookie(key, strValue) {Expires = expires};
        _response.Cookies.Set(cookie);
    }
    
    // ... see code sample for full implementation
}

Here’s a sample unit tests that proves the testability of this code. I use Moq as my mocking framework.

public static class Mocks
{
    public static Mock<HttpRequestBase> HttpRequest()
    {
        var httpRequest = new Mock<HttpRequestBase>();
        httpRequest.Setup(x => x.Cookies).Returns(new HttpCookieCollection());
        return httpRequest;
    }

    public static Mock<HttpResponseBase> HttpResponse()
    {
        var httpResponse = new Mock<HttpResponseBase>();
        httpResponse.Setup(x => x.Cookies).Returns(new HttpCookieCollection());
        return httpResponse;
    }
}

// This method is from my CookieContainerTests class

[TestMethod]
public void SetValue_UpdatesExistingCookie()
{
    // Arrange
    const string cookieName = "myCookie";
    const string cookieValue = "myValue";
    DateTime cookieExpires = new DateTime(2009, 1, 1, 0, 0, 0);

    var httpRequest = Mocks.HttpRequest();
    var httpResponse = Mocks.HttpResponse();
    var cookieContainer = new CookieContainer(httpRequest.Object, httpResponse.Object);
    
    httpResponse.Object.Cookies.Add(new HttpCookie(cookieName, "oldValue"));

        // Act
    _cookieContainer.SetValue(cookieName, cookieValue, cookieExpires);

    // Assert
    HttpCookie cookie = httpResponse.Object.Cookies["myCookie"];
    Assert.IsNotNull(cookie);
    Assert.AreEqual(cookie.Name, cookieName);
    Assert.AreEqual(cookie.Value, cookieValue);
    Assert.AreEqual(cookie.Expires, cookieExpires);
}

That’s it! Now you have a testable and reusable cookie container!

How to use it in your application

It’s really easy to integrate this into your app! Just create an interface that defines all your application-specific properties you want to save in cookies and a concrete implementation of this interface that interacts with the cookie container.

public interface IAppCookies
{
    string UserEmail { get; set; }
    DateTime? LastVisit { get; set; }
}

public class AppCookies : IAppCookies
{
    private readonly ICookieContainer _cookieContainer;

    public AppCookies(ICookieContainer cookieContainer)
    {
        _cookieContainer = cookieContainer;
    }

    public string UserEmail
    {
        get { return _cookieContainer.GetValue("UserEmail"); }
        set { _cookieContainer.SetValue("UserEmail", value, DateTime.Now.AddDays(10)); }
    }

    public DateTime? LastVisit
    {
        get { return _cookieContainer.GetValue<DateTime?>("LastVisit"); }
        set { _cookieContainer.SetValue("LastVisit", value, DateTime.Now.AddDays(10)); }
    }
}

You can now inject this IAppCookies interface to your MVC Controller:

public class HomeController : Controller
{
    private readonly IAppCookies _cookies;

    public HomeController(IAppCookies cookies)
    {
        _cookies = cookies;
    }

    public ActionResult Index()
    {
        DateTime currentTime = DateTime.Now;

        IndexViewModel viewModel = new IndexViewModel
        {
            CurrentTime = currentTime,
            LastVisit = (_cookies.LastVisit ?? currentTime),
            UserEmail = _cookies.UserEmail
        };

        _cookies.LastVisit = currentTime;

        return View(viewModel);
    }

    public class IndexViewModel
    {
        public string UserEmail { get; set; }
        public DateTime LastVisit { get; set; }
        public DateTime CurrentTime { get; set; }
    }
}

Wow, you’re still reading :-)

That’s all I want to show here! If you want to see more about how the IOC is set up (I’m using StructureMap) or anything else, take a look at the full code:

I looking forward to hearing your feedback on this!

Thanks for reading,
Christian Weiss

Technorati-Tags: ,,,

Tags: , , , ,

Use wrappers to access your cookies, sessions, …

by cweiss 26. January 2009 18:45

As described in my previous post, I will give you some more details about how you can access your cookies in a type-safe and easy way!

Update: Read the follow up post

The simplest way to do this is by using a little wrapper class like this one:

using System;
using System.Globalization;
using System.Web;

namespace CookieWrapper.Web
{
    public static class MyCookies
    {
        public static string UserEmail
        {
            get { return GetValue("UserEmail"); }
            set { SetValue("UserEmail", value, DateTime.Now.AddDays(10)); }
        }

        public static DateTime? LastVisit
        {
            get
            {
                string strDate = GetValue("LastVisit");
                if (String.IsNullOrEmpty(strDate))
                    return null;
                return DateTime.Parse(strDate, CultureInfo.InvariantCulture);
            }
            set
            {
                string strDate = value.HasValue ? value.Value.ToString(CultureInfo.InvariantCulture) : null;
                SetValue("LastVisit", strDate, DateTime.Now.AddDays(10));
            }
        }

        private static string GetValue(string key)
        {
            HttpCookie cookie = HttpContext.Current.Request.Cookies[key];
            if (cookie != null)
                return cookie.Value;
            return null;
        }

        private static void SetValue(string key, string value, DateTime expires)
        {
            HttpContext.Current.Response.Cookies[key].Value = value;
            HttpContext.Current.Response.Cookies[key].Expires = expires;
        }
    }
}

All you have to do is create a static property for every cookie that you would like to work with. As you can see you also have the Expires-times administrated in one single place!

Now you can access the values as seen below and you don’t have to worry about the cookie implementation-details in every place.

tbLastVisit.Text = MyCookies.UserEmail;
MyCookies.LastVisit = DateTime.Now; 

Of course, you can also use this same approach for working with session data or any other key-based collection.

Thanks for reading,
Christian Weiss

Technorati-Tags: ,,

Tags: ,

Don’t use Response.Cookies[string] to check if a cookie exists!

by cweiss 26. January 2009 15:57
Technorati-Tags: ,

Update: Follow Up Posts

The short explanation, if you don’t like to read the entire story

If you use code like “if (Response.Cookies[“mycookie”] != null) { … }”, ASP.Net automatically generates a new cookie with the name “mycookie” in the background and overwrites your old cookie! Always use the Request.Cookies-Collection to read cookies!

The long explanation and some useful advices at the end

You can access the Cookies-Collection in two different places in ASP.Net:

  • Request.Cookies gives you the cookies that are sent from the browser to your server.
  • With Response.Cookies, you can send cookies from your server to the browser.

Storing cookies

To make your life easier (or harder, as you will see later), ASP.Net gives you the possibility to add a cookie to the browser this way:

Response.Cookies["mycookie"].Value = "some value"; 
Response.Cookies["mycookie"].Expires = DateTime.Now.AddDays(10);

As you can see here, the .net framework automatically generates the HttpCookie instance with the name “mycookie” in the background and adds it to the collection.

image

Sending cookies to the browser this way is perfectly fine.

Reading Cookies

The important thing you have to know when reading cookies is, that the Response.Cookies collection is empty at the beginning of every request. The cookie with the name “mycookie” can only be found in the Request.Cookies-Collection!

If you use the following line to check the cookie, a new cookie with the name “mycookie” and an empty value gets added to the Response.Cookies Collection and this overwrites your old cookie! (See framework code above!)

if (Response.Cookies["mycookie"] != null) 
{ 
    // This automatically overwrites the existing cookie with an empty value!!! 
}

The correct way to access cookies is by using the Request.Cookies-Collection:

if (Request.Cookies["mycookie"] != null) 
{ 
    // This is fine 
}

So remember the following rules

  • To read cookies, ALWAYS use the Request.Cookies-Collection
  • Only use the Response.Cookies to set or change cookies

How can I make it better and more beautiful?

Accessing the Request.Cookies or Response.Cookies collection directly is lame! You can’t easily test this code and you don’t have all the other cool stuff like type safety and IntelliSense for the keys.

I will write a follow-up post right after this one with an detailed example on how you can do it better!

Thanks for reading,
Christian Weiss

Tags: ,

I’d like to announce … myself!

by cweiss 26. January 2009 15:56

I don’t know why, but due to some reasons, you stumbled upon this page! I’m happy to announce, that this page is going to be my attempt to make the world a better place for you – at least if you are a Microsoft .Net developer and if you – like me – love to learn new things!

“WTF? Yet another blog about programming?”

If that’s what you are thinking right now, then my answer is “Maybe! But hopefully not!”. I will give my best to provide you with high quality information and if it saves you some hours then it served its purpose!

What can you expect from this blog?

I’m a web developer and software architect. The things I like working with are constantly changing, as I really like to dive into new technologies! Currently I’m learning a lot about ASP.Net MVC and all the ALT.Net topics, so these will be the first topics I’m going to write about.

Your English is crap! Stop hurting my eyes!

I’m from Austria and I speak German (with some crazy dialect)! That means, English is not my first language! This blog is a great opportunity for me to get my hands dirty and just improve my English knowledge! Please feel free to write comments and correct me, if you have found some disastrous mistakes.

Stop talking, start writing!

That’s enough said for my first post! Hopefully, I’ve awaken your interest a little bit and you will visit my page again. Expect to reading from me soon!

Thanks for reading,
Christian Weiss

Tags:

Personal

About the author

Christian Weiss is a Software Developer and Software Architect from Austria and is also one of the ".Net Usergroup South Austria" leaders.

Page List

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2013 chwe.at