Featured Post

Understanding Tuples in .NET 4.0 and .NET 2.0/3.0/3.5

.NET 4.0 introduces a new type, the Tuple. In mathematics, a tuple is an ordered set of elements, e.g. (1, 2, 3, 4, 5) is a 5-tuple. In programming (i.e. type theory) a tuple has a fixed size and the underlying type of its components is explicit. With this in mind, we can understand tuples simply as...

Read More

Caching the Generic Way

Posted by Matthew Abbott | Posted in .NET, Development | Posted on 25-01-2010

Tags: , , ,

0

Often is the case when you’re creating an application (be it web or not) the need for caching can become a critical part of software design. You can be faced with a myriad of designs and mechanisms used to store objects, and the specifics of how each container works from one implementation to the next can differ greatly.

What we can do thoough is abstract the implementation away and provide a generic, type-safe way of accessing a cache of objects, as well as provide additional expiration functionality and grouping. Basically, we want to be able to call:

Person me = Cache<Person>.Fetch("me");

…or:

Person me = Cache<Person>.Fetch("me", () => new Person("Matthew", "Abbott"));

At its most basic, the caching framework should allow us to get objects, and if objects don’t exist, go ahead and create them and store them automatically. It should be just as easy for single and multiple objects:

var people = Cache<Person>.FetchAll(() => GetAllPeople());

A brief description of the major types involved with the framework:

  • ICacheProvider – The interface to define a cache provider.
  • CachedItem – An item stored in a cache.
  • CachingGroup – The type used to group sets of items.
  • CacheBinding – A binding between a type, a CachingGroup and a specific provider.
  • CacheManager – A manager type used for accessing provider functions.
  • Cache – The generic type used for accessing caches.
  • IExpirable – The interface to define an expirable item.

As a big fan of the Provider model, it made sense to design the framework as such, creating the need for a cache provider interface, or ICacheProvider. The interface need only provide the methods used for managing the cache, that being Fetch, FetchAll, Store, Remove and RemoveAll. Now there could be many overloaded versions of each method, but we can handle the overloads later with a different type, all the provider is really concerned with is the actual operation. Here is my ICacheProvider interface:

    public interface ICacheProvider
    {
        IEnumerable<T> FetchAll<T>(CachingGroup cachingGroup, Func<IEnumerable<T>> getFunction, Func<T, string> keyFunction, Func<T, ExpirationSettings> expiryFunction);

        T Fetch<T>(string key, CachingGroup cachingGroup, Func<string, T> getFunction, Func<string, T, ExpirationSettings> expiryFunction);

        void Store<T>(string key, T value, CachingGroup cachingGroup, ExpirationSettings expirySettings);

        void Store<T>(IEnumerable<T> items, CachingGroup cachingGroup, Func<T, string> keyFunction, Func<string, T, ExpirationSettings> expiryFunction);

        void Remove<T>(string key, CachingGroup cachingGroup);

        void RemoveAll<T>(CachingGroup cachingGroup);
    }

A look at the methods:

  • FetchAll(..) – Used for fetching multiple items. If no items exist in the cache, the getFunction delegate can be used to get some instances to store, and in the same vein, the keyFunction and expiryFunction delegates can be used for creating keys and expiration settings respectively.
  • Fetch(…) – Used for fetching a single item. The key is required, and we are explictly trying to find a specific item.
  • Store(string key, T value, …) – Used to storing a single instance with the specified key.
  • Store(IEnumerable items, …) – Used for storing multiple instances. As with FetchAll(), a keyFunction can be provided for generating an item specific key.
  • Remove(…) and RemoveAll(…) – Used for removing items from the cache.

A colleague asked about implementing a Clear() method, this current version does not implement such a method, but it could be considered for a later version.

When an item is requested using the generic Cache type (this itself is static), a call is made to the cache manager to firstly identify the cache provider being used for the requested type, and also the caching group (if applicable. In its simplest:

The cache manager maintains an internal list of bindings which govern the behaviour of how the cache manager interacts with specific providers. For example, you could choose to store Person items in one cache, but store Person items with a specific CachingGroup in another.

So we can see that its easy to grab items from the cache, and Storing items is much the same. The model allows for a fine amount of control over how each cache behaves, as the actual storing and retrieving of items is down to the provider itself, your code doesn’t need to worry about that.

One thing the provider interface doesn’t deal with specifically is item (or group) expiry. With the current version of the framework, our base implementation, CacheProviderBase provides methods for determining whether or not an item (or group) has expired. When an item is pulled from the cache, its expiry is updated and then checked. If the item is valid, we can return it, otherwise we return the default for the required type.

        protected virtual Tuple<bool, T> ResolveValue<T>(CachedItem<T> cachedItem)
        {
            Throw.IfArgumentNull(cachedItem, "cachedItem");

            if (cachedItem.CachingGroup != null) {
                cachedItem.CachingGroup.UpdateExpiry();
            }
            cachedItem.UpdateExpiry();

            if (cachedItem.CachingGroup != null && cachedItem.CachingGroup.HasExpired()) {
                Remove<T>(cachedItem.Key, cachedItem.CachingGroup);
                return new Tuple<bool, T>(false, default(T));
            }

            if (cachedItem.HasExpired()) {
                Remove<T>(cachedItem.Key, cachedItem.CachingGroup);
                return new Tuple<bool, T>(false, default(T));
            }

            return new Tuple<bool, T>(true, cachedItem.Value);
        }

The return type Tuple is a wrapper type designed on the same principle of .NET 4.0’s Tuple. This is a v2.0/3.0/3.5 compatible project, when it gets upgraded to .NET 4.0, the project-domain Tuple type can be removed in favour of .NET’s own implementation.

Where are you likely to use this in actual implementations? At work we are busy working away converting our existing website into a database driven, content-managed website. As content and meta information doesn’t change often we can get away with caching data in the HttpRuntime.Cache. To this end, we’ve implemented a HttpRuntimeCacheProvider which does just that. In fact the current version of the framework creates a HttpRuntimeCacheProvider as the default provider for web applications (we also have a HashtableCacheProvider and a couple of others pre-built).

I’ve attached the project for you’re viewing, let me know what you think and how it can be improved.

CachingFramework.rar

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter

Understanding Tuples in .NET 4.0 and .NET 2.0/3.0/3.5

Posted by Matthew Abbott | Posted in Uncategorized | Posted on 05-01-2010

Tags: , ,

0

.NET 4.0 introduces a new type, the Tuple. In mathematics, a tuple is an ordered set of elements, e.g. (1, 2, 3, 4, 5) is a 5-tuple. In programming (i.e. type theory) a tuple has a fixed size and the underlying type of its components is explicit.

With this in mind, we can understand tuples simply as a wrapper type of two or more values, e.g.:

  var person = new Tuple<string, int>("Matt", 25);
  // person.Item1 ...
  // person.Item2

Whilst we wait for .NET 4.0 to come a’knocking, we can still capture this functionality with v2.0 of the framework, thanks to generics. We can define our own Tuple types, for instance:

namespace MyTuples
{
    using System;
    using System.Globalization;

    /// <summary>
    /// Represents a finite 2-item tuple.
    /// </summary>
    /// <typeparam name="TFirst">The type of the first item.</typeparam>
    /// <typeparam name="TSecond">The type of the second item.</typeparam>
    public class Tuple<TFirst, TSecond> : IEquatable<Tuple<TFirst, TSecond>>
    {
        #region Constructors
        /// <summary>
        /// Initialises a new instance of <see cref="Tuple{TFirst,TSecond}" />.
        /// </summary>
        public Tuple() { }

        /// <summary>
        /// Initialises a new instance of <see cref="Tuple{TFirst,TSecond}" />.
        /// </summary>
        /// <param name="first">The first item.</param>
        public Tuple(TFirst first)
        {
            this.First = first;
        }

        /// <summary>
        /// Initialises a new instance of <see cref="Tuple{TFirst,TSecond}" />.
        /// </summary>
        /// <param name="first">The first item.</param>
        /// <param name="second">The second item.</param>
        public Tuple(TFirst first, TSecond second)
        {
            this.First = first;
            this.Second = second;
        }
        #endregion

        #region Properties
        /// <summary>
        /// Gets or sets the first item.
        /// </summary>
        public TFirst First { get; set; }

        /// <summary>
        /// Gets or sets the second item.
        /// </summary>
        public TSecond Second { get; set; }
        #endregion

        #region Methods

        /// <summary>
        /// Calculates the hash code for this tuple.
        /// </summary>
        /// <returns>The hash code for this tuple.</returns>
        private int CalculateHashCode()
        {
            int hashCode = 0;

            TFirst first = default(TFirst);
            TSecond second = default(TSecond);

            if (!object.Equals(this.First, first)) {
                hashCode += this.First.GetHashCode();
            }

            if (!object.Equals(this.Second, second)) {
                hashCode += this.Second.GetHashCode();
            }

            return hashCode;
        }

        /// <summary>
        /// Gets the hash code for this tuple.
        /// </summary>
        /// <returns>The hash code for this tuple.</returns>
        public override int GetHashCode()
        {
            return CalculateHashCode();
        }

        /// <summary>
        /// Determines if this instance equals the specified tuple.
        /// </summary>
        /// <param name="other">The other tuple to compare to.</param>
        /// <returns>True if this instance equals the specified tuple, otherwise false.</returns>
        public bool Equals(Tuple<TFirst, TSecond> other)
        {
            if (other == null) {
                return false;
            }

            return (this.GetHashCode() == other.GetHashCode());
        }

        /// <summary>
        /// Determines if the two instances equal.
        /// </summary>
        /// <param name="firstTuple">The first tuple to compare.</param>
        /// <param name="secondTuple">The second tuple to compare.</param>
        /// <returns>True if the two instances are equal, otherwise false.</returns>
        public static bool Equals(Tuple<TFirst, TSecond> firstTuple, Tuple<TFirst, TSecond> secondTuple)
        {
            if (firstTuple == null && secondTuple == null) {
                return true;
            }

            if (firstTuple == null || secondTuple == null) {
                return false;
            }

            return firstTuple.Equals(secondTuple);
        }

        /// <summary>
        /// Determines if this instance equals the specified object.
        /// </summary>
        /// <param name="obj">The other object to compare to.</param>
        /// <returns>True if this instance equals the specified object, otherwise false.</returns>
        public override bool Equals(object obj)
        {
            if (obj == null) {
                return false;
            }

            if (obj is Tuple<TFirst, TSecond>) {
                return Equals(obj as Tuple<TFirst, TSecond>);
            }

            Type first = typeof(Tuple<TFirst, TSecond>);
            Type second = obj.GetType();

            throw new NotSupportedException(
                string.Format(CultureInfo.CurrentUICulture,
                              "Cannot check for equality between types '{0}' and '{1}'.",
                              first.Name,
                              second.Name));
        }
        #endregion
    }
}

But where would this be any use? We’ve all seen this before:

public Result DoSomething() {
  return new Result
  {
    Name = "Matt",
    Age = 25
  };
}

…and perhaps the even more face aching:

public void DoSomething(out string name, out int age) {
  name = "Matt";
  age = 25;
}

Often is the case when you have a function that you want to return multiple values, you resort to either one of the methods described above. This often results in your class library expanding rapidly due to the large number of these wrapper types who’s only purpose is to contain other types.

We could in fact solve this issue using a Tuple:

public Tuple<string, int> DoSomething() {
  return new Tuple<string, int>("Matt", 25);
}

Now, you could go one step further…how about an extension method that joins enumerations of types into Tuples?

namespace MyTuples
{
    using System;
    using System.Collections.Generic;
    using System.Linq;

    static class IEnumerableExtensions
    {
        #region Methods
        /// <summary>
        /// Converts the given enumerations to 2-part tuples.
        /// </summary>
        /// <typeparam name="TFirst">The type of the first item in the tuple.</typeparam>
        /// <typeparam name="TSecond">The type of the second item in the tuple.</typeparam>
        /// <param name="items">The first set of items.</param>
        /// <param name="secondItems">The second set of items.</param>
        /// <param name="includeUnmatched">Should we include unmatched items?</param>
        /// <returns>An enumeration of 2-part tuples created from the given sets.</returns>
        public static IEnumerable<Tuple<TFirst, TSecond>> ToTuples<TFirst, TSecond>(
            this IEnumerable<TFirst> items,
            IEnumerable<TSecond> secondItems, bool includeUnmatched)
        {
            if (items == null) {
                throw new ArgumentNullException("items");
            }

            if (secondItems == null) {
                throw new ArgumentNullException("secondItems");
            }

            TFirst[] firstArray = items.ToArray();
            TSecond[] secondArray = secondItems.ToArray();
            IList<Tuple<TFirst, TSecond>> results = new List<Tuple<TFirst, TSecond>>();

            int i = 0;

            for (; i < firstArray.Length; i++) {
                if (i < secondArray.Length) {
                    results.Add(new Tuple<TFirst, TSecond>(firstArray[i], secondArray[i]));
                } else if (includeUnmatched) {
                    results.Add(new Tuple<TFirst, TSecond>(firstArray[i], default(TSecond)));
                }
            }

            if (includeUnmatched && (i < secondArray.Length)) {
                for (; i < secondArray.Length; i++) {
                    results.Add(new Tuple<TFirst, TSecond>(default(TFirst), secondArray[i]));
                }
            }

            return results;
        }

        /// <summary>
        /// Converts the given enumerations to 2-part tuples.
        /// </summary>
        /// <typeparam name="TFirst">The type of the first item in the tuple.</typeparam>
        /// <typeparam name="TSecond">The type of the second item in the tuple.</typeparam>
        /// <param name="items">The first set of items.</param>
        /// <param name="secondItems">The second set of items.</param>
        /// <returns>An enumeration of 2-part tuples created from the given sets.</returns>
        public static IEnumerable<Tuple<TFirst, TSecond>> ToTuples<TFirst, TSecond>(
            this IEnumerable<TFirst> items,
            IEnumerable<TSecond> secondItems)
        {
            return ToTuples(items, secondItems, false);
        }
        #endregion
    }
}

What these methods allow us to do is create Tuples from each of the items. These examples are only using 2-tuple instances, but you can create Tuples and extension methods for however many types you want to wrap.

Given the above code, I could then do something like this:

string[] names = { "Matt", "Andy", "Chris" };
int[] ages = { 25, 30, 28 };

var people = names.ToTuples(ages);
foreach (var person in people)
{
    Console.WriteLine("Name: {0}, Age: {1}", person.First, person.Second);
}

Thanks to type inference, we don’t need to explictly state the types of the items in the tuples, the compiler will handle this for us. Nicey nicey eh?

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter

Database driven MVC Routing

Posted by Matthew Abbott | Posted in .NET, Development | Posted on 23-12-2009

Tags: , , , ,

0

I’m not overly keen on hard coding MVC routes in the application, so I’ve come up with a nice way of pulling the routes out of the application, and into a Sql Server table. All nicely wrapped up with Linq-to-Sql.

We begin, by planning our database tables. We need to be flexible enough to store both the routes, and route parameters, so that’s exactly what we do. Our Route table can hold both active and ignored routes, here’s my design:

Routes have parameters, but parameters also have defaults and constraints (we don’t really cover constraints with this version, but we can advance on that in the future). One of the difficulties establishing routes outside of code, is denoting the type of the parameter. I’ve designed the RouteParameter table to take this into consideration:

Then with a bit of added drop and drag, we can create out Linq-to-Sql entities:

How does this all tie up? Well, when the application starts, we can then poll our database for routes to add. We create a registration method, which accesses our DataContext and pulls out any routes. We handle our ignore routes first, and then create our active routes.

/// <summary>
/// Registers the configured routes.
/// </summary>
public void RegisterRoutes()
{
    using (DataContext context = DataContext.CreateDataContext())
    {
        var allRoutes = (from r in context.Routes
                         select r);

        var ignoredRoutes = (from r in allRoutes
                             where r.Ignore == true
                             select r);

        foreach (var route in ignoredRoutes)
        {
            if (route.IsEnabled())
            {
                RouteTable.Routes.IgnoreRoute(route.Pattern);
            }
        }

        var activeRoutes = (from r in allRoutes
                            where r.Ignore == false || r.Ignore == null
                            orderby r.Index descending
                            select r);

        foreach (var route in activeRoutes)
        {
            if (route.IsEnabled())
            {
                MapRoute(context, route);
            }
        }
    }
}

We then take care of our route mapping:

/// <summary>
/// Maps the given <see cref="BusinessObjects.Route" /> to the route table.
/// </summary>
/// <param name="context">The <see cref="DataContext" /> used to read the route.</param>
/// <param name="route">The route to map.</param>
private static void MapRoute(DataContext context, BusinessObjects.Route route)
{
    var parameters = (from p in context.RouteParameters
                      where p.Route == route.Id
                      select p);

    var defaults = new RouteValueDictionary();
    var constraints = new RouteValueDictionary();

    foreach (var param in parameters)
    {
        if (!defaults.ContainsKey(param.Name))
        {
            if (param.DefaultValue != null)
            {
                if (string.IsNullOrEmpty(param.Type))
                {
                    defaults.Add(param.Name, null);
                }
                else
                {
                    defaults.Add(param.Name, GetInstance(param.Type, param.DefaultValue));
                }
            }
            else
            {
                defaults.Add(param.Name, null);
            }
        }

        if (param.Constraint != null)
        {
            constraints.Add(param.Name, param.Constraint);
        }
    }

    RouteTable.Routes.Add(
        route.Key, new System.Web.Routing.Route(route.Pattern, new MvcRouteHandler())
                   {
                       Defaults = defaults,
                       Constraints = constraints
                   });
}

Important note: Don’t use the RouteTable.Routes.MapRoute method when passing in an instance of RouteValueDictionary for defaults and constraints. The MapRoute method provided by MVC creates the dictionaries itself, so you end up with dictionaries within dictionaries, and the routing will fail.

For any parameters that specify a default value and a declared typed, we need to handle the casting of that type. We can use a TypeConverter to handle this, so thats what we’ve done here:

/// <summary>
/// Gets an instance of the specified type with the given value.
/// </summary>
/// <param name="typeName">The typeName for the required type.</param>
/// <param name="value">The value to assign to this type.</param>
/// <returns>An instance of the specified type.</returns>
private static object GetInstance(string typeName, string value)
{
    if (string.IsNullOrEmpty(typeName))
    {
        throw new ArgumentException(
            string.Format(
                CultureInfo.CurrentUICulture, Resources.Shared.Exception_ArgumentNullOrEmpty, "typeName"),
            "typeName");
    }

    Type type = Type.GetType(typeName);
    if (type == null)
    {
        throw new InvalidOperationException(
            string.Format(
                CultureInfo.CurrentUICulture, Resources.Shared.Exception_CannotGetType, typeName));
    }

    TypeConverter converter = TypeDescriptor.GetConverter(type);
    if (converter == null)
    {
        throw new InvalidOperationException(
            string.Format(
                CultureInfo.CurrentUICulture, Resources.Shared.Exception_NoTypeConverter, type.FullName));
    }

    if (!converter.CanConvertFrom(typeof(string)))
    {
        throw new InvalidOperationException(
            string.Format(
                CultureInfo.CurrentUICulture, Resources.Shared.Exception_CannotConvertFromString, type.FullName));
    }

    return converter.ConvertTo(value, type);
}

If a valid TypeConverter exists for our target type, we should be able to handle conversion of custom types too.

So our complete application type is as such:

namespace MvcFramework.Web
{
    using System;
    using System.ComponentModel;
    using System.Globalization;
    using System.Linq;
    using System.Web.Mvc;
    using System.Web.Routing;
    using MvcFramework.BusinessObjects;

    /// <summary>
    /// Provides services for Http Applications
    /// </summary>
    public class Application : System.Web.HttpApplication
    {
        #region Methods
        /// <summary>
        /// Registers the configured routes.
        /// </summary>
        public void RegisterRoutes()
        {
            using (DataContext context = DataContext.CreateDataContext())
            {
                var allRoutes = (from r in context.Routes
                                 select r);

                var ignoredRoutes = (from r in allRoutes
                                     where r.Ignore == true
                                     select r);

                foreach (var route in ignoredRoutes)
                {
                    if (route.IsEnabled())
                    {
                        RouteTable.Routes.IgnoreRoute(route.Pattern);
                    }
                }

                var activeRoutes = (from r in allRoutes
                                    where r.Ignore == false || r.Ignore == null
                                    orderby r.Index descending
                                    select r);

                foreach (var route in activeRoutes)
                {
                    if (route.IsEnabled())
                    {
                        MapRoute(context, route);
                    }
                }
            }
        }

        /// <summary>
        /// Refreshes the route table.
        /// </summary>
        public void RefreshRoutes()
        {
            RouteTable.Routes.Clear();
            RegisterRoutes();
        }

        /// <summary>
        /// Maps the given <see cref="BusinessObjects.Route" /> to the route table.
        /// </summary>
        /// <param name="context">The <see cref="DataContext" /> used to read the route.</param>
        /// <param name="route">The route to map.</param>
        private static void MapRoute(DataContext context, BusinessObjects.Route route)
        {
            var parameters = (from p in context.RouteParameters
                              where p.Route == route.Id
                              select p);

            var defaults = new RouteValueDictionary();
            var constraints = new RouteValueDictionary();

            foreach (var param in parameters)
            {
                if (!defaults.ContainsKey(param.Name))
                {
                    if (param.DefaultValue != null)
                    {
                        if (string.IsNullOrEmpty(param.Type))
                        {
                            defaults.Add(param.Name, null);
                        }
                        else
                        {
                            defaults.Add(param.Name, GetInstance(param.Type, param.DefaultValue));
                        }
                    }
                    else
                    {
                        defaults.Add(param.Name, null);
                    }

                    if (param.Constraint != null)
                    {
                        constraints.Add(param.Name, param.Constraint);
                    }
                }
            }

            RouteTable.Routes.Add(
                route.Key, new System.Web.Routing.Route(route.Pattern, new MvcRouteHandler())
                           {
                               Defaults = defaults,
                               Constraints = constraints
                           });
        }

        /// <summary>
        /// Gets an instance of the specified type with the given value.
        /// </summary>
        /// <param name="typeName">The typeName for the required type.</param>
        /// <param name="value">The value to assign to this type.</param>
        /// <returns>An instance of the specified type.</returns>
        private static object GetInstance(string typeName, string value)
        {
            if (string.IsNullOrEmpty(typeName))
            {
                throw new ArgumentException(
                    string.Format(
                        CultureInfo.CurrentUICulture, Resources.Shared.Exception_ArgumentNullOrEmpty, "typeName"),
                    "typeName");
            }

            Type type = Type.GetType(typeName);
            if (type == null)
            {
                throw new InvalidOperationException(
                    string.Format(
                        CultureInfo.CurrentUICulture, Resources.Shared.Exception_CannotGetType, typeName));
            }

            TypeConverter converter = TypeDescriptor.GetConverter(type);
            if (converter == null)
            {
                throw new InvalidOperationException(
                    string.Format(
                        CultureInfo.CurrentUICulture, Resources.Shared.Exception_NoTypeConverter, type.FullName));
            }

            if (!converter.CanConvertFrom(typeof(string)))
            {
                throw new InvalidOperationException(
                    string.Format(
                        CultureInfo.CurrentUICulture, Resources.Shared.Exception_CannotConvertFromString, type.FullName));
            }

            return converter.ConvertTo(value, type);
        }

        /// <summary>
        /// Initialises the application.
        /// </summary>
        protected void Application_Start()
        {
            RegisterRoutes();
        }
        #endregion
    }
}

Let me know what you think.

Note (again): Ignore the usage of IsEnabled(), its just an extension method I’ve created for an interface my entity types implement.

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter

Interesting thought…

Posted by Matthew Abbott | Posted in .NET, Development | Posted on 19-12-2009

Tags: ,

0

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter

Url remapping could be the source of your ViewState validation woes!

Posted by Matthew Abbott | Posted in .NET, Development | Posted on 14-12-2009

Tags: , , , , , ,

0

At work, we’re preparing a new release of the website, and came across an issue regarding ViewState validation. You may (or hopefully may not) have come across the following error before:

Validation of viewstate MAC failed. If this application is hosted by a Web Farm or cluster, ensure that  configuration specifies the same validationKey and validation algorithm. AutoGenerate cannot be used in a cluster.

Or the even less helpful:

Unable to validate data.

Now originally, I thought this was something to do width MAC validation of the ViewState. But this is on a local machine, not a web farm. I shouldn’t need to worry about the MachineKey because of that. Hmmm…

Now, this only happens on two of our critical landing pages, which again was odd. They all inherit from the same base type, they all do exactly the same thing, albeit with different textual copy, so why would it happen?

Turns out, its our dynamic url remapping. When we do a Server.Transfer the ViewState validation fails, because the target page is not the same url as the remapped page we came from. The solution is simple, change the Form.Action property of the page to point to the remapped page:

protected new void Page_Load(object sender, EventArgs e)
{
    base.Page_Load(sender, e);

    Form.Action = "/{remapped-url-here}.aspx";
}

Quite obvious now I think about it.

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter

httpErrors, customErrors and 404s

Posted by Matthew Abbott | Posted in .NET | Posted on 03-12-2009

Tags: , , , , , , , , , ,

0

Came across an interesting scenario today. Well actually, it started yesterday, it just took me ages to figure out whats going on.

Ok, the scenario; We have an ASP.NET application, that uses custom error pages, and also a rather robust logging framework. Here’s how we have our custom errors configured:

<customErrors mode="On">
	<error statusCode="404" redirect="~/PageNotFound.aspx" />
</customErrors>

Now, since migrating our website to the behemoth that is IIS7, we can now configure custom errors at the web server, through httpErrors:

<httpErrors>
	<remove statusCode="404" />
	<error statusCode="404" responseMode="ExecuteURL" path="/PageNotFound.aspx" />
</httpErrors>

Now typically our custom error page will respond with a status code of 404. Although this is normally not required because the customError handler of ASP.NET will handle this for you, if you visit the page directly, you really should set the 404 response code, if only to ensure that the page doesn’t get indexed by search engines.

In our PageNotFound.aspx page, we log our 404 to let us know what happened, but we are finding we are actually getting two notices from the page.

public partial class PageNotFound : Page {

	#region Methods
	public void Page_Load() {
		Response.StatusCode = 404;
		Logger.Log(...);
	}
	#endregion
}

So, why is this happening?

Turns out, when ASP.NET has finished processing our PageNotFound.aspx request, IIS then kicks in and realises we have returned a 404, so it’s own error handling takes over. In our current configuration, we’re telling it to execute the url ‘/PageNotFound.aspx’. That sorts that one out then, IIS is executing the same page on the same request, which means the page processes twice, hence the two responses.

Now, we can’t change the responseMode of the IIS custom error entry because the alternative settings won’t work. ‘File’ won’t allow us to process the PageNotFound.aspx file with ASP.NET, and Redirect ends up creating a cyclic redirect, as the redirect creates a whole new request, which again reports a 404, which IIS then performs anothe redirect and yadayadayada.

I finally found the answer, its a setting for httpErrors called existingResponse. Now, when this setting is set to ‘PassThrough’, the error module will determine if the response it received from earlier in the request pipeline already has a response body. If it does, it simply returns the existing response, instead of performing the custom action:

<httpErrors existingResponse="PassThrough">
	<remove statusCode="404" />
	<error statusCode="404" responseMode="ExecuteURL" path="/PageNotFound.aspx" />
</httpErrors>

So now, we’re still performing our custom error handling correctly, and the good news is, we correctly process the page once.

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter

Epic Fan-Art

Posted by Matthew Abbott | Posted in Personal | Posted on 14-08-2009

Tags: ,

0

Another daily search on Deviantart, and I found two gems, which are pretty damn impressive:

Source: Sonic by =gureiduson and Super Sonic by *MRi.

Damn, if only I could produce something as awesome as that!

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter

Consuming .NET Types from Javascript

Posted by Matthew Abbott | Posted in .NET, Development, Javascript | Posted on 13-08-2009

Tags: , , , ,

1

One of the things I’ve found most compelling about mixing up server-side and client-side technologies, is Javascript’s fantastic ability of generating on the fly objects. There are two parts to this awesome little trick, firstly, serialising the object at the server, and reading it at the client.

We’ll imagine, that we have a User list that we want to make available to the client, so let’s design our model.

public class User {

	#region Properties
	public string Username { get; set; }
	public string Password { get; set; }
	public string Forename { get; set; }
	public string Surname { get; set; }
	#endregion
}

There are a number of ways of serialising objects in .NET, but the one we are interested in is JSON (Javascript Object Notation, http://www.json.org). JSON is a lightweight data interchange format that Javascript can evaluate as an object. Now, without Mvc’s goodness, you kinda have to do things yourself, and to do that, you need the DataContractJsonSerializer (which you can find with a reference to System.ServiceModel.Web). Let’s decorate our class and mark the various member’s that we want to serialise.

using System.Runtime.Serialization;

[DataContract]
public class User {

	#region Properties
	[DataMember]
	public string Username { get; set; }

	public string Password { get; set; }

	[DataMember]
	public string Forename { get; set; }

	[DataMember]
	public string Surname { get; set; }
	#endregion
}

By using the DataContract and DataMember attributes, we are marking what members of what types are available to be serialised. This is good because it allows you to customise exactly what members you want, and hide others you don’t. In the above example, we won’t bother making the User.Password property available to the client.

The next step, is to simply call the serialisation, which we’ll dump straight into a HttpResponse output stream.

// Create out sample object instance.
User user = new User() {
	Username = "admin",
	Password = "password",
	Forename = "Matthew",
	Surname = "Abbott"
};

// We need to modify the content type so it is interpretted correctly by the browser.
Response.ContentType = "application/javascript";

// Serialise the object, and write it straight to the output stream.
DataContractJsonSerializer serialiser = new DataContractJsonSerializer(typeof(User));
serialiser.WriteObject(Response.OutputStream, user);

// We can safely close the output stream, nothing more to write.
Response.End();

Thats our server stuff done! Now comes the interesting part!

For the client-side, I always tend to choose JQuery (http://www.jquery.com) over any other Javascript framework, it’s just *easy*, and what’s even easier is getting our JSON content, as JQuery has nice little support method that automatically evaluates the JSON response for us. getJSON is the key, but of course you can setup your request manually by using $.ajax(…) instead.

var getUser = function(username, callback) {
	$.getJSON("UserEndpoint.aspx", { "username": username }, function(result) {
		if (callback) {
			callback(result);
		}
	});
};

$(function() {

	getUser("admin", function(result) {
		alert(result.Forename + " " + result.Surname);
	});
});

And thats it! But wait…what about ASP.NET Mvc I hear you ask? With Mvc, its even easier, as those thoughtful boys over at the ASP.NET Mvc team thought to create the JsonResult, which doesn’t even require you to use the DataContractJsonSerializer! Just chuck a POCO (Plain Old CLR Object) at it, and it should hopefully just go straight ahead and prep some JSON goodness for you.

public ActionResult GetUsername(string username) {
	// We won't both doing some lookup, let's just create out dummy user.
	User user = new User() {
		Username = "admin",
		Password = "password",
		Forename = "Matthew",
		Surname = "Abbott"
	};

	return Json(user);
};

Just update your Ajax calls to suit.

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter