// ASP.NET MVC: Replacing the default ActionInvoker to do something useful with non-ActionResult return types
// See more: http://notherdev.blogspot.com/2012/09/non-actionresult-return-type-aspnet-mvc.html
public class MyControllerFactory : DefaultControllerFactory
{
    public override IController CreateController(RequestContext context, string controllerName)
    {
        var controller = base.CreateController(context, controllerName);
        return ReplaceActionInvoker(controller);
    }

    private IController ReplaceActionInvoker(IController controller)
    {
        var mvcController = controller as Controller;
        if (mvcController != null)
            mvcController.ActionInvoker = new ControllerActionInvokerWithDefaultJsonResult();
        return controller;
    }
}

public class ControllerActionInvokerWithDefaultJsonResult : ControllerActionInvoker
{
    public const string JsonContentType = "application/json";

    protected override ActionResult CreateActionResult(ControllerContext controllerContext, ActionDescriptor actionDescriptor, object actionReturnValue)
    {
        if (actionReturnValue == null)
            return new EmptyResult();

        return (actionReturnValue as ActionResult) ?? new ContentResult()
        {
            ContentType = JsonContentType,
            Content = JsonConvert.SerializeObject(actionReturnValue)
        };
    }
}