March 2009 - Posts

The Controller class of ASP.NET MVC Framework has few overloaded methods to return json result from the controller actions. Internally it uses the JavaScriptSerializer which was introduced in ASP.NET AJAX Framework. But unlike the DataContractJsonSerializer which works on attributes, the only way you can control the json output in JavaScriptSerializer class is by registering the JavaScriptConverter classes. In most of the cases you don’t have to control the way the json data is shaping, but in some situation you might need to step in. If you check the overloaded Json methods, none of it takes the JavaScriptConverters as argument.

protected internal JsonResult Json(object data);

protected internal JsonResult Json(object data, string contentType)

protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding)

And in the ExecuteResult method of JsonResult it does not register the JavaScriptConverters from the from the web.config.

public override void ExecuteResult(ControllerContext context)
{
    if (context == null)
    {
        throw new ArgumentNullException("context");
    }

    HttpResponseBase response = context.HttpContext.Response;

    if (!String.IsNullOrEmpty(ContentType))
    {
        response.ContentType = ContentType;
    }
    else
    {
        response.ContentType = "application/json";
    }
    if (ContentEncoding != null)
    {
        response.ContentEncoding = ContentEncoding;
    }
    if (Data != null)
    {
        // The JavaScriptSerializer type was marked as obsolete prior to .NET Framework 3.5 SP1
        #pragma warning disable 0618
        var serializer = new JavaScriptSerializer();
        response.Write(serializer.Serialize(Data));
        #pragma warning restore 0618
    }
}

And I think it is a Designing defect/bug.

The Resolution:

First we will create a class which will inherit from the JsonResult, it will have an extra property Converters, so from Controllers you can pass the JavaScriptConverter classes and it will also lookup in the configuration for the registered JavaScriptConverter classes.

public class CorrectJsonResult : JsonResult
{
    public IList<JavaScriptConverter> Converters
    {
        get;
        set;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }

        HttpResponseBase response = context.HttpContext.Response;

        response.ContentType = !string.IsNullOrEmpty(ContentType) ? ContentType : "application/json";

        if (ContentEncoding != null)
        {
            response.ContentEncoding = ContentEncoding;
        }

        if (Data != null)
        {
            JavaScriptSerializer serializer = CreateJsonSerializer();

            response.Write(serializer.Serialize(Data));
        }
    }

    private JavaScriptSerializer CreateJsonSerializer()
    {
        JavaScriptSerializer serializer = new JavaScriptSerializer();

        ScriptingJsonSerializationSection section = ConfigurationManager.GetSection("system.web.extensions/scripting/webServices/jsonSerialization") as ScriptingJsonSerializationSection;

        if (section != null)
        {
            if ((section.Converters != null) && (section.Converters.Count > 0))
            {
                IEnumerable<JavaScriptConverter> converters = CreateConvertersFrom(section.Converters);
                serializer.RegisterConverters(converters);
            }

            serializer.MaxJsonLength = section.MaxJsonLength;
            serializer.RecursionLimit = section.RecursionLimit;
        }

        if ((Converters != null) && (Converters.Count > 0))
        {
            serializer.RegisterConverters(Converters);
        }

        return serializer;
    }

    private static IEnumerable<JavaScriptConverter> CreateConvertersFrom(ConvertersCollection typeDefinitions)
    {
        foreach (Converter definition in typeDefinitions)
        {
            Type type = BuildManager.GetType(definition.Type, false);

            if (type == null)
            {
                throw new ArgumentException("Unknown type.", definition.Type);
            }

            if (!typeof(JavaScriptConverter).IsAssignableFrom(type))
            {
                throw new ArgumentException("Unsupported type.", definition.Type);
            }

            yield return (JavaScriptConverter) Activator.CreateInstance(type);
        }

        yield break;
    }
}

As you can see we are not only registering the converters, we are also setting the appropriate MaxJsonLength and RecursionLimit from the configuration section(system.web.extensions/scripting/webServices/jsonSerialization).

Next, we will create an abstract Controller for the above fixed JsonResult.

public abstract class CorrectJsonResultController : Controller
{
    protected override JsonResult Json(object data, string contentType, Encoding contentEncoding)
    {
        return Json(data, contentType, contentEncoding, new List<JavaScriptConverter>());
    }

    protected virtual CorrectJsonResult Json(object data, string contentType, Encoding contentEncoding, IEnumerable<JavaScriptConverter> converters)
    {
        return new CorrectJsonResult
                   {
                       Data = data,
                       ContentType = contentType,
                       ContentEncoding = contentEncoding,
                       Converters = new List<JavaScriptConverter>(converters)
                   };
    }
}

I have filled a bug, if you want it fixed in the next version of ASP.NET MVC, do vote it.

Download: CorrectJson.zip

Shout it

With the new System.Web.Abstraction namespace we can now easily write unit testable HttpModule and HttpHandler. In this post, I will show you how to write unit testable HttpModule and HttpHandler.

Prior the release of System.Web.Abstraction the problem with unit testing of these web infrastructural items is HttpContext, it is sealed, no way to mock it with Rhino or Moq. The only option is to create the wrapper objects of these non-mockable objects but it has a very long tail like HttpRequest, HttpResponse, HttpSessionState, HttpServerUtility etc etc. And this is the exact thing that the System.Web.Abstraction provides, all wrappers around the non-mockable objects of HttpContext. But still, both the HttpModule and HttpHandler depends upon the original HttpContext which I hope will change in ASP.NET 4.0. till then we need to create a super layer for making it Unit Testable.

HttpModule

public abstract class BaseHttpModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.BeginRequest += (sender, e) => OnBeginRequest(new HttpContextWrapper(((HttpApplication) sender).Context));
        context.Error += (sender, e) => OnError(new HttpContextWrapper(((HttpApplication) sender).Context));
        context.EndRequest += (sender, e) => OnEndRequest(new HttpContextWrapper(((HttpApplication) sender).Context));
    }

    public void Dispose()
    {
    }

    public virtual void OnBeginRequest(HttpContextBase context)
    {
    }

    public virtual void OnError(HttpContextBase context)
    {
    }

    public virtual void OnEndRequest(HttpContextBase context)
    {
    }
}

You can hook the other events if it is required for your application. Now lets create a basic HttpModule which will remove the www from the url:

public class RemoveWwwModule : BaseHttpModule
{
    public override void OnBeginRequest(HttpContextBase context)
    {
        const string Prefix = "http://www.";

        string url = context.Request.Url.ToString();

        bool startsWith3W = url.StartsWith(Prefix, StringComparison.OrdinalIgnoreCase);

        if (startsWith3W)
        {
            string newUrl = "http://" + url.Substring(Prefix.Length);

            HttpResponseBase response = context.Response;

            response.StatusCode = (int) HttpStatusCode.MovedPermanently;
            response.Status = "301 Moved Permanently";
            response.RedirectLocation = newUrl;
            response.SuppressContent = true;
            response.End();
        }
    }
}

Unit Test:

public class RemoveWwwModuleFixture
{
    private readonly Mock<HttpContextBase> _httpContext;
    private readonly Mock<HttpRequestBase> _httpRequest;
    private readonly Mock<HttpResponseBase> _httpResponse;

    public RemoveWwwModuleFixture()
    {
        _httpContext = new Mock<HttpContextBase>();
        _httpRequest = new Mock<HttpRequestBase>();
        _httpResponse = new Mock<HttpResponseBase>();

        _httpContext.SetupGet(context => context.Request).Returns(_httpRequest.Object);
        _httpContext.SetupGet(context => context.Response).Returns(_httpResponse.Object);
    }

    [Fact]
    public void OnBeginRequest_Should_Redirect_When_Requesting_Url_Which_Starts_With_WWW()
    {
        _httpRequest.SetupGet(request => request.Url).Returns(new Uri("http://www.mysite.com/"));

        _httpResponse.SetupSet(response => response.StatusCode = (int) HttpStatusCode.MovedPermanently);
        _httpResponse.SetupSet(response => response.Status = "301 Moved Permanently");
        _httpResponse.SetupSet(response => response.RedirectLocation = "http://mysite.com/");
        _httpResponse.SetupSet(response => response.SuppressContent = true);
        _httpResponse.Setup(response => response.End());

        var module = new RemoveWwwModule();

        module.OnBeginRequest(_httpContext.Object);

        _httpResponse.VerifyAll();
    }
}

HttpHandler

public abstract class BaseHttpHandler : IHttpHandler
{
    public virtual bool IsReusable
    {
        get
        {
            return false;
        }
    }

    public void ProcessRequest(HttpContext context)
    {
        ProcessRequest(new HttpContextWrapper(context));
    }

    public abstract void ProcessRequest(HttpContextBase context);
}

Now lets create an HttpHandler which combines few JavaScript files, I will be skipping the combine part as it is not relevant to this post.

public class JavaScriptHandler : BaseHttpHandler
{
    public override void ProcessRequest(HttpContextBase context)
    {
        string content = GetContent();
        HttpResponseBase response = context.Response;

        response.ContentType = "application/x-javascript";
        response.Write(content);
    }

    private string GetContent()
    {
        return "YOUR JAVA SCRIPT FILES CONTENT";
    }
}

Unit Test:

public class JavaScriptHandlerFixture : IDisposable
{
    private readonly Mock<HttpContextBase> _httpContext;
    private readonly Mock<HttpResponseBase> _httpResponse;

    private readonly JavaScriptHandler _handler;

    public JavaScriptHandlerFixture()
    {
        _httpContext = new Mock<HttpContextBase>();
        _httpResponse = new Mock<HttpResponseBase>();

        _httpContext.SetupGet(context => context.Response).Returns(_httpResponse.Object);

        _handler = new JavaScriptHandler();
    }

    public void Dispose()
    {
        _httpResponse.VerifyAll();
    }

    [Fact]
    public void ProcessRequest_Should_Set_Correct_ContentType()
    {
        _httpResponse.SetupSet(response => response.ContentType = "application/x-javascript");

        _handler.ProcessRequest(_httpContext.Object);
    }

    [Fact]
    public void ProcessRequest_Should_Write_Content()
    {
        _httpResponse.Setup(response => response.Write(It.IsAny<string>()));

        _handler.ProcessRequest(_httpContext.Object);
    }
}

If you want see more Unit Testable HttpModule and HttpHandler, go checkout the source of KiGG.

Shout it

Last night the forehead four head has released the 1st chapter of their upcoming Wrox book along with a sample project NerdDinner and I think this is the best application to check if anyone is trying to lean the new ASP.NET MVC framework.

And this is the list of currently available Open Source Projects developed in ASP.NET MVC. I am ordering it based upon the complexity and learning curve according to my understanding:

  1. NerdDinner
  2. CodeBetter Award
  3. CodeCampServer
  4. BeerHouse
  5. StoreFront
  6. Oxite
  7. KiGG
  8. FubuMVC/AltOxite (Eric Hexter is absolutely right it does not has any dependency on System.Web.MVC)

Updated (03-13-2009)

There are few more, but I did not had a chance to check those:

  1. FlickrXplorer
  2. CarTrackr
  3. Cuyahoga
  4. BlogSharp
  5. AzureIssueTracker
  6. BlogSvc.net

Updated (03-17-2009)

I think, I should also list the framework/architecture:

  1. MVC Contrib
  2. S#arp Architecture

David Hyden seems also maintaining a list. Go check it out.

Happy ASP.NET MVC learning !!!

Shout it

Recently, in KiGG/DotNetShoutout we have integrated Twitter, nothing complex, very basic thing like when a story is submitted or appears in the front page it will broadcast in Twitter and like our feed it will post the short url of the original story (Cant resist to do some shameless marketing for DotNetShoutout).

Since it is a new requirement, initially I have modified the StoryService constructor to include the twitter client as a new argument and use it after the story is added in the database, the code is something like the following:

//Other codes

//Add it in database
_storyRepository.Add(story);

//Increase User Score
_userScoreService.StorySubmitted(byUser);

// Send Trackback
PingStory(content, story, detailUrl);

//Ping the Feed Servers
PingServers();

//Send Tweet
_twitter.UpdateStatus(story);

result = new StoryCreateResult { NewStory = story, DetailUrl = detailUrl };

return result;

As you can see there are quite a few things that I have do:

  • Increase the User Score.
  • Send Trackback (Thank you for submitting this cool story)
  • Ping Feedburner/Pingomatic/technorati servers.
  • Send Tweet.

So for this new requirement we have to modify it and will again have to do if we add more features in future and we do have a plan to implement the Spy/Log (don’t confuse it with the code logger, it is ajax view which shows what is happening currently in the application) and this obviously not a path we should follow. It violets the OCP completely, tie us to write some transactional script  kind of code. We need to find a way where we can add new features without modifying the StoryService. One option would be to pass an array of IBackgroundService (As these are noting but some background services)in the StoryService constructor which these classes will implement and later on the StoryService will call the Execute method of each background service. But Story Submit, Story Publish is more like a system event which should be globally available.

Enter Event Aggregator

As per Martin Fowler “An Event Aggregator acts as a single source of events for many objects. It registers for all the events of the many objects allowing clients to register with just the aggregator.” Jeremy D Miller also used this pattern in his excellent Build your own CAB series. And recently I was browsing through the CompositeWpf/Prism code and found the EventAggregator which seems a perfect candidate for my situation. According to its documentation:

“The EventAggregator service is primarily a container for events that allow decoupling of publishers and subscribers so they can evolve independently.”

EventAggregator

But it has some dependency on .NET WPF which I would like to remove, and after talking with Glen Block, he confirmed that since it is licensed under MS-PL, I can copy and modify it according to my need. Also most of the example you will find of Event Aggregator demonstrate the UI events, but it is a very powerful pattern and can be used in non UI events too which we will see next.

As mentioned in the above that UserScoreService, PingStory, PingServer, SendTweet is some kind of background task which can be run independently and it will act as subscriber in the above diagram, so lets create an interface:

public interface IBackgroundTask
{
    bool IsRunning
    {
        get;
    }

    void Start();

    void Stop();
}

Next we will create an abstract class which will implement this interface to reduce the duplicate codes:

public abstract class BaseBackgroundTask : IBackgroundTask
{
    private readonly IEventAggregator _eventAggregator;

    protected BaseBackgroundTask(IEventAggregator eventAggregator)
    {
        if (eventAggregator == null)
        {
            throw new ArgumentNullException("eventAggregator");
        }

        _eventAggregator = eventAggregator;
    }

    public bool IsRunning
    {
        get;
        private set;
    }

    protected IEventAggregator EventAggregator
    {
        get
        {
            return _eventAggregator;
        }
    }

    public void Start()
    {
        OnStart();
        IsRunning = true;
    }

    public void Stop()
    {
        OnStop();
        IsRunning = false;
    }

    protected abstract void OnStart();

    protected abstract void OnStop();

    protected SubscriptionToken Subscribe<TEvent, TEventArgs>(Action<TEventArgs> action) where TEvent : BaseEvent<TEventArgs> where TEventArgs : class
    {
        return EventAggregator.GetEvent<TEvent>().Subscribe(action, true);
    }

    protected void Unsubscribe<TEvent>(SubscriptionToken token) where TEvent : BaseEvent
    {
        EventAggregator.GetEvent<TEvent>().Unsubscribe(token);
    }
}

Now lets create some concrete implementation of these background tasks.

First, the Twitter:

public class SendTweet : BaseBackgroundTask
{
    private SubscriptionToken _storySubmitToken;

    public SendTweet(IEventAggregator eventAggregator) : base(eventAggregator)
    {
    }

    protected override void OnStart()
    {
        if (!IsRunning)
        {
            _storySubmitToken = Subscribe<StorySubmitEvent, StorySubmitEventArgs>(StorySubmitted);
        }
    }

    protected override void OnStop()
    {
        if (IsRunning)
        {
            Unsubscribe<StorySubmitEvent>(_storySubmitToken);
        }
    }

    private void StorySubmitted(StorySubmitEventArgs eventArgs)
    {
        UpdateStatus(eventArgs.Story);
    }

    private void UpdateStatus(Story story)
    {
        //Update Twitter status goes here
    }
}

Next the UserScoreService:

public class UserScoreService : BaseBackgroundTask
{
    private SubscriptionToken _storySubmitToken;

    public UserScoreService(IEventAggregator eventAggregator) : base(eventAggregator)
    {
    }

    protected override void OnStart()
    {
        if (!IsRunning)
        {
            _storySubmitToken = Subscribe<StorySubmitEvent, StorySubmitEventArgs>(StorySubmitted);
        }
    }

    protected override void OnStop()
    {
        if (IsRunning)
        {
            Unsubscribe<StorySubmitEvent>(_storySubmitToken);
        }
    }

    private void StorySubmitted(StorySubmitEventArgs eventArgs)
    {
        IncreaseUserScore(eventArgs.Story.PostedBy);
    }

    private void IncreaseUserScore(User user)
    {
        // Increase user score goes here
    }
}

I am skipping the PingStory and PingServer as they are very much same as above.

Next the published part, now the StoryService will forward the StorySubmit event to EventAggregator instead of calling these class individually.

//Other codes

//Add it in database
_storyRepository.Add(story);

//Publish the event
_eventAggregator.GetEvent<StorySubmitEvent>().Publish(new StorySubmitEventArgs(story, detailUrl));

result = new StoryCreateResult { NewStory = story, DetailUrl = detailUrl };

return result;

And now we have to ensure that these background services can start listing this event. So lets create a BootstrapperTask which I have shown in my previous post.

public class StartBackgroundTasks : IBootstrapperTask
{
    private readonly IBackgroundTask[] _tasks;

    public StartBackgroundTasks(IBackgroundTask[] tasks)
    {
        _tasks = tasks;
    }

    public void Execute()
    {
        foreach(IBackgroundTask task in _tasks)
        {
            task.Start();
        }
    }
}

And at last the wiring of Unity container, I am using the fluent version but you can also use the xml configuration if you want.

IUnityContainer container = new UnityContainer();

container.RegisterType<IBackgroundTask, UserScoreService>("userScore", new ContainerControlledLifetimeManager())
         .RegisterType<IBackgroundTask, SendTweet>("sendTweet", new ContainerControlledLifetimeManager())
         .RegisterType<IBackgroundTask, PingStory>("pingStory", new ContainerControlledLifetimeManager())
         .RegisterType<IBackgroundTask, PingServer>("pingServer", new ContainerControlledLifetimeManager())
         .RegisterType<IEventAggregator, EventAggregator>(new ContainerControlledLifetimeManager())
         .RegisterType<IControllerFactory, CommonServiceLocatorControllerFactory>(new ContainerControlledLifetimeManager())
         .RegisterType<IBootstrapperTask, RegisterRoutes>("route", new ContainerControlledLifetimeManager(), new InjectionConstructor(new [] { RouteTable.Routes}))
         .RegisterType<IBootstrapperTask, RegisterControllerFactory>("controllerFactory", new ContainerControlledLifetimeManager())
         .RegisterType<IBootstrapperTask, StartBackgroundTasks>("startBackgroundTasks", new ContainerControlledLifetimeManager())
         .RegisterType<IFormsAuthentication, FormsAuthenticationService>(new ContainerControlledLifetimeManager())
         .RegisterType<IMembershipService, AccountMembershipService>(new InjectionConstructor())
         .RegisterType<AccountController>()
         .RegisterType<HomeController>();

ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(container));

My initial plan was to refer you the KiGG/DotNetShoutout source code rather than posting a separate version, but as you know that ASP.NET MVC RC2 has released few days ago I would rather upgrade it to that version.

Further Reference:

Comments/Suggestions?

Download: EventAggregator.zip

Shout it

If you are a TDD purist, you should know that accessing file system in Unit Test is violating the rule. But in our application, our infrastructural code often requires to access the configuration values form web.config/app.config. In this post, I will show you how can create a simple wrapper class which you can use in your unit tests without hitting the file system.

First, create a interface which will allow us to access the common sections of the configuration file:

public interface IConfigurationManager
{
    NameValueCollection AppSettings
    {
        get;
    }

    string ConnectionStrings(string name);

    T GetSection<T>(string sectionName);
}

Next, the implementation:

using System.Collections.Specialized;
using System.Configuration;

public class ConfigurationManagerWrapper : IConfigurationManager
{
    public NameValueCollection AppSettings
    {
        get
        {
            return ConfigurationManager.AppSettings;
        }
    }

    public string ConnectionStrings(string name)
    {
        return ConfigurationManager.ConnectionStrings[name].ConnectionString;
    }

    public T GetSection<T>(string sectionName)
    {
        return (T) ConfigurationManager.GetSection(sectionName);
    }
}

This is a very common pattern which you will find all over in the new ASP.NET 3.5 SP1 System.Web.Abstraction. The rule is whatever thing is not unit testable, create an interface with the exact same signature and create a wrapper class which internally calls the corresponding method/property.

Now lets say, we would like to do some processing with some configuration values like the following (By the way the Process() is a poor example):

public void Process()
{
    string appVersion = _configuration.AppSettings["version"];
    string connectionString = _configuration.ConnectionStrings("myDatabase");

    OutputCacheSettingsSection settings = _configuration.GetSection<OutputCacheSettingsSection>("system.web/caching/outputCacheSettings");
    int duration = 0;

    if (settings.OutputCacheProfiles.Count > 0)
    {
        OutputCacheProfile profile = settings.OutputCacheProfiles.Get("MyProfile");

        if (profile != null)
        {
            duration = profile.Duration;
        }
    }

    //Now perform operation with these values;
}

Now, we can write the unit test like the following which does not requires the web.config/app.config file:

[Fact]
public void Test_Process()
{
    _configuration.Expect(c => c.AppSettings).Returns(new NameValueCollection{ { "version", "1.0" } });
    _configuration.Expect(c => c.ConnectionStrings(It.IsAny<string>())).Returns(@"Data Source=.\SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=True");

    OutputCacheProfile cacheProfile = new OutputCacheProfile("MyProfile") { Duration = 360 };
    OutputCacheSettingsSection cacheSection = new OutputCacheSettingsSection();
    cacheSection.OutputCacheProfiles.Add(cacheProfile);

    _configuration.Expect(c => c.GetSection<OutputCacheSettingsSection>(It.IsAny<string>())).Returns(cacheSection);

    _processor.Process();
}

Enjoy!!!

Download: UnitTestableConfiguration.zip

Shout it
More Posts