Spruce and CacheStack

Spruce

I recently created a library that compliments the fantastic Dapper library. I called my library Spruce as a play on the word dapper. The spruce library contains a set of extension methods that simplify querying and saving. When I’m in working in .net land, I primarily use MS Sql server 2008+, so that is what the library is written against. Until I have a need (or get a pull request), I don’t have plans to extend the library to support other databases.

In addition to the querying and saving extensions, Spruce also includes sql schema helpers and a basic migration framework. The migration framework is a simple forward-only (no rollbacks) code based migrations. There are a number of attributes, that can be added to your POCO classes, to define the basic schema for your data. To complement the attributes, Spruce offers a set of extensions specifically for manipulating sql schemas. There are extensions ranging from creating and dropping tables to column schema manipulation. The migration framework ensures that your schema is always where you want it. In cases where there isn’t an extension to accomplish the migration that you need, you can always run the raw sql script via Db.Execute().

Spruce is available as a nuget and is also available on github. There is detailed example usage available at the project’s github page. If you’re interested in seeing Spruce in a real-world project, it is being used with the MvcKickstart project.

 

CacheStack

The other library that I recently created is all about caching. It’s called CacheStack and compliments ServiceStack’s ICacheClient. CacheStack extends typical caching scenarios with the notion of a cache context, allowing you to clear cache items without knowing the specific cache keys. You’re able to setup listeners for the items that you cache and have those cache items invalidate when one of the items you’re listening to fires a trigger. The cache context supports cache profiles that can be defined any way you prefer, be it database, config files, etc. CacheStack also includes a modified version of MvcDonutCaching. My version of donut caching has some bugfixes, performance improvements, and uses ICacheClient for persistence. The really cool part is that you can leverage all of the features of a cache context when using donut caching. This makes it very trivial to clear the output cache of an action, when a model object is updated.

CacheStack is available as a nuget and is also available on github. Like Spruce, there is detailed example usage available on the project’s github page. CacheStack will be incorporated into MvcKickstart in the near future.

Configuring MVC 4 with StructureMap

I started a new MVC4 project and wanted to use StructureMap for my IOC container of choice. I followed Phil’s post about wiring up dependency resolvers in mvc 4, but I kept getting the following error: “StructureMapDependencyResolver does not appear to implement Microsoft.Practices.ServiceLocation.IServiceLocator.
Parameter name: commonServiceLocator”

Took a little digging, but I found the CommonServiceLocator project from the Microsoft Patterns and Practice group.  That project has a StructureMap implementation of the IServiceLocator interface for StructureMap.  After I installed the CommonServiceLocator nuget, I was able to reference IServiceLocator in my code.   Taking the code from the CommonServiceLocator implementation, I ended up with the following:

The following code will setup mvc to use structuremap as the dependency resolver. Add the webactivator nuget and toss the following file in your app_start folder:

using System.Web.Mvc;
using MvcKickstart.Infrastructure;
using StructureMap;

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(YourProject.IocConfig), "PreStart", Order = -100)]

// This gets installed automatically with the MvcKickstart nuget (https://nuget.org/packages/mvckickstart)
namespace YourProject 
{
  public static class IocConfig
	{
		public static void PreStart() 
		{
			// If changes need to be made to IocRegistry, please subclass it and replace the following line
			ObjectFactory.Initialize(x => x.AddRegistry(new IocRegistry(typeof(IocConfig).Assembly)));
			DependencyResolver.SetResolver(new StructureMapDependencyScope(ObjectFactory.Container));
		}
	}
}

Hope this helps someone looking to do the same!

Using The Google Analytics API With Asp.Net MVC

I’m a big fan of wordpress and really like the Google Analyticator plugin. It provides a dashboard widget that summarizes your analytics stats. I was working on a project that had a relatively sparse admin dashboard and figured I would provide a similar view of analytics stats. The main difference is that the project I was working on was an asp.net mvc3 project.

I searched for some analytics api examples for asp.net and didn’t really find much. So hopefully this will help someone who is looking to consume gdata apis from .net. All of the code is available on github for your viewing pleasure.

What does it look like?

Authenticating with Google Data Api

Authenticating with Google is pretty simple.  Google supports a variety of authentication methods including OAuth2.  I’m not entirely sure why, but I chose to go with their AuthSub method of authentication.  Basically, you redirect the user to a specific Google url, they authorize your application and are returned to your application with a token.  You can then use that token for one-time operation or convert the token to a long lasting token that can be used repeatedly.

The code I use to authenticate looks like:

I store the long lasting token in an embedded instance of RavenDb. It’s a quick & super easy way to store things like that.

Querying Analytics

Now that you have a token from the user, you can query analytics to get data for any site that the user has access to.  Google sites have a unique id associated with them, that Google calls TableId.  You need to specify this value with any analytic data query.  In order to get a list of available sites, you’ll need to query the account feed:

With that snippet, I organize the sites based on their associated account.

After choosing a specific site to work with, you can query information like total page views, average amount of time spent on the site, etc.  The data feed explorer is quite handy in exploring the type of data that Analytics will return.  For example, the following query will get a number of general stats across all pages:

Similarly, you can add dimensions to your query.  Dimensions allow you to group the metrics data, similar to sql group by.  The following query will get a list of pages sorted by most page views:

The UI side of things

The graph is generated using the jquery sparkline plugin. While not as sexy as the official analytics graphs, it works for a quick view. Everything else on the page is styled with twitter bootstrap, with a few minor tweaks.

Conclusion

That’s about it.  Have a look at the complete project to get a full understanding of how I used the analytics api to build an asp.net mvc widget that summarizes website analytics.

Hello Rails

This year, I began to explore worlds outside of .net, as more than a lurker, and I want to continue to share my steps along the way. This is one of those steps…

Background

The DMB Stream community has grown more than I had ever envisioned when I first created the site. To help celebrate that and give back to the community, I wanted to run a Facebook contest. I read long ago that Heroku and Facebook have a partnership where you can host your Facebook app on Heroku for free. This means no server configuration and it just works 🙂  I have been meaning to make a site with rails, but always fell back into my comfort zone of .net.  Not this time…

Getting Started

I fired up a virtual image of mac osx (I will get a dedicated box as I become more comfortable with non windows environments) and started down the path of installing my development environment.  I used the Rails Ultimate Install Guide and other answers from this StackOverflow post to get the majority of my development tools setup.  Outside of that, I had my trusty Agile Web Development With Rails book next to me to hold my hand throughout this journey.

I should make a side note: I chose to use Heroku’s MongoHQ for persisting data.  They offer free data storage with Mongo, up to 16MB.  I don’t feel I need a relational database and MongoHQ seemed like the easiest route to take for saving contest submissions.

Riding Rails

Since this is my first rails app, it took a bit longer than I expected to get up and running.  That and I made a point to get comfortable with vim which took time as well.  I supplemented the rails book with the getting started guide on the rails wiki.  It compliments my rails book with basic things like hooking up the root route.

After a day or so of using vim, I decided to check out Textmate to see how that compares.  Coming from Visual Studio, I can definitely say that I am more at home using Textmate over vim.  I’m happy I learned vim and have basic usage down.  I know I could continue to improve my efficiency with vim, but I really like the project like view that Textmate offers.  Being able to quickly select any file in the rails tree is a major deciding factor for me.

As far as rails itself goes, I have really enjoyed working with that framework.  Rails feels between one and two major releases ahead of asp.net mvc.  All of the built in helpers, asset pipeline, etc are all time savers and magically work with no configuration/custom code.  The only thing that feels less mature than asp.net mvc is validation.  Rails has model validation, but I have yet to find something along the lines of the unobtrusive jquery validation that asp.net mvc provides.  That doesn’t mean it isn’t out there…

That’s one of the downfalls that I have found regarding Rails.  Finding up to date information for the current version of rails isn’t the easiest thing in the world.  There’s a lot of blog posts and examples out there for rails and a good chunk of those are for older rails versions.  Sometimes the examples work, sometimes the latest version of rails looks nothing like what’s in the example.

Heroku, GitHub, and Mongo

What can I say about Heroku? It’s amazing and such a pleasure to use; I don’t see myself using another rails host at this point.  They continue to innovate and offer solutions with the same vigor that Amazon does with their web services.  Heroku pricing is extremely attractive as well.  Host any number of small sites for free and they’ll scale on demand, when that time comes.  Deploying to heroku is so simple and easy… MS could learn a lot from them (that is, if there are any passionate people left on that stack).  Yes, I understand that there is AppHarbor, but deployment options for .net are outdated, limited, and overall complete shit.

Not much to say about GitHub either… it’s what everyone uses these days for source control.  I used both the command line git client and GitHub’s mac client with my project.  Both have benefits and the gui client is so simple and elegant… I still really enjoy Kiln for my .net projects, but I’ll be in git land for everything else.

I chose to go with MongoHQ for data persistence.   MongoHQ and Heroku have a partnership that provides the free 16MB plan to each heroku app.  If your app requires more storage than that, MongoHQ price levels won’t break your bank.  There are no license fees or worries about infrastructure.  MongoHQ has multiple libraries available for non rails environments as well (including .net and java).  They even have a similar partnership with AppHarbor.  Rails by default is setup to use ActiveRecord and a relational database.  Have no fear, it’s easy to override those defaults and MongoMapper wraps mongo in a way that makes working with it feel very similar to a traditional database.

Conclusion

While I was building this application, I found myself thinking that I should be doing busy work type things, but there really isn’t a lot of that to do with the rails stack.  For small/medium sized sites, it’s geared to help you realize your ideas rather than getting lost in architecture and useless technical rants.  To get started, that’s all I need… If the site ever gets too big or cost prohibitive for rails, it should monetize itself enough at that point to facilitate alternatives.

At this point, I’m planning out my next project and will be using the same frameworks to make it a reality.  It’s more complicated than a simple facebook app, so it should be a nice next step for my rails experience.

I feel that innovation and excitement have long moved away from the Microsoft stack and the trend seems to continue among developers.  There are many other things going on out there and in general, it feels like .net is treading water and playing catch up.

As slanted as this post may seem, I haven’t given up on .net.  I still have a fondness for it, but I would be stupid to ignore the rest of the web.

Howto: Install non-authorized apk files on AT&T android phones

I don’t know why this has to be so difficult, but these are the steps I took to install my development apk file to a test droid phone:

  1. Make sure I have the Android SDK installed on my PC (Required for Droid Explorer)
  2. Download and install HTC Sync – If the htc site search is broken, Google to the rescue
  3. Connect the phone to your PC via USB and select HTC Sync as the connection type
  4. Download and install Droid Explorer from http://de.codeplex.com/
  5. Right click the apk file and select install
Hope this helps someone…

Access the wordpress browser check api from asp.net

New versions of WordPress have a pretty handy widget included with the admin dashboard.  The widget checks the version of the browser that the user is running (via the user agent) and alerts them if it is insecure (ie6) or has an upgrade (Firefox 3.x).  I wanted to include a similar widget with Acturent and if possible, take advantage of their service api.

After a short time tinkering, I have a nice c# wrapper to their api.  The code below uses a class called BiaCache that is basically a wrapper around System.Web.Cache or an in-memory dictionary, based on if System.Web.Cache exists.  A slight modification will be needed based on your usage.  I cache the results for a week, based on the user agent.

To deserialize the string that comes back from the WordPress service, I found the Sharp Serialization Library works well.

Basic usage for my helper is:

var browserInfo = new HappyBrowsingHelper().GetBrowserInfo(Request.UserAgent);

The results from the web service get stored in a model object called BrowserInfo:

public class BrowserInfo
{
  public string Name { get; set; }
  public string Version { get; set; }
  public string Url { get; set; }
  public string ImageUrl { get; set; }
  public string CurrentVersion { get; set; }
  public bool HasUpgrade { get; set; }
  public bool IsInsecure { get; set; }
}

The helper method to make the service call is as follows:

public BrowserInfo GetBrowserInfo(string userAgent)
{
  if (string.IsNullOrWhiteSpace(userAgent))
    return new BrowserInfo();

  var key = "__GetBrowserInfo_" + userAgent;
  var item = BiaCache.Get<BrowserInfo>(key);
  if (item == null)
  {
    string serializedResponse = null;
    try
    {
      var postData = "useragent=" + userAgent;

      var request = WebRequest.Create("http://api.wordpress.org/core/browse-happy/1.0/");
      request.Method = "POST";
      request.ContentType = "application/x-www-form-urlencoded";
      request.ContentLength = postData.Length;
      using (var writeStream = request.GetRequestStream())
      {
        var encoding = new UTF8Encoding();
        var bytes = encoding.GetBytes(postData);
        writeStream.Write(bytes, 0, bytes.Length);
      }

      using (var response = request.GetResponse())
      {
        using (var responseStream = response.GetResponseStream())
        {
          using (var reader = new StreamReader(responseStream, Encoding.UTF8))
          {
            serializedResponse = reader.ReadToEnd();
          }
        }
      }

      var serializer = new PhpSerializer();
      var result = (Hashtable) serializer.Deserialize(serializedResponse);
      item = new BrowserInfo
          {
              Name = ToStringOrNull(result["name"]),
              Version = ToStringOrNull(result["version"]),
              Url = ToStringOrNull(result["update_url"]),
              ImageUrl = ToStringOrNull(result["img_src_ssl"]),
              CurrentVersion = ToStringOrNull(result["current_version"]),
              HasUpgrade = (bool) result["upgrade"],
              IsInsecure = (bool) result["insecure"]
          };

      BiaCache.Add(key, item, (int) TimeSpan.FromDays(7).TotalMinutes, System.Web.Caching.CacheItemPriority.AboveNormal);
    }
    catch (Exception ex)
    {
      Log.Fatal("Error getting browser info from wordpress :( nUser agent: " + userAgent + "nResult: " + (serializedResponse ?? string.Empty) + "nn" + ex, ex);
      item = new BrowserInfo();
    }
  }
  return item;
}

private static string ToStringOrNull(object o)
{
  return o == null ? null : o.ToString();
}

Thats basically about it…  Happy browsing!  You can download a demo project: HappyBrowsingDemo.

FreeTextExpression for NHibernate 3.2

I upgraded to the latest NHibernate 3.2 and found my FreeText AbstractCriterion wasn’t working as it previously did.  This updated version works for me:

[Serializable]
public class FreeTextExpression : AbstractCriterion
{
  private readonly string _propertyName;
  private readonly object _value;
  private readonly IProjection _projection;

  /// <summary>
  /// Initializes a new instance of the <see cref="FreeTextExpression"/> class.
  /// </summary>
  /// <param name="projection">The projection.</param>
  /// <param name="value">The value.</param>
  public FreeTextExpression(IProjection projection, object value)
  {
    _projection = projection;
    _value = value;
  }

  /// <summary>
  /// Initialize a new instance of the <see cref="FreeTextExpression" />
  /// class for a named Property and its value.
  /// </summary>
  /// <param name="propertyName">The name of the Property in the class.</param>
  /// <param name="value">The value for the Property.</param>
  public FreeTextExpression(string propertyName, object value)
  {
    _propertyName = propertyName;
    _value = value;
  }

  public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters)
  {
    var sqlBuilder = new SqlStringBuilder();
    var columnNames = CriterionUtil.GetColumnNames(_propertyName, _projection, criteriaQuery, criteria, enabledFilters);

    if (columnNames.Length != 1)
    {
      throw new HibernateException("Contains may only be used with single-column properties");
    }

    sqlBuilder.Add("freetext(")
      .Add(columnNames[0])
      .Add(",");

    sqlBuilder.Add(criteriaQuery.NewQueryParameter(GetParameterTypedValue(criteria, criteriaQuery)).Single());
    sqlBuilder.Add(")");

    return sqlBuilder.ToSqlString();
  }

  public override TypedValue[] GetTypedValues(ICriteria criteria, ICriteriaQuery criteriaQuery)
  {
    var typedValues = new List<TypedValue>();

    if (_projection != null)
    {
      typedValues.AddRange(_projection.GetTypedValues(criteria, criteriaQuery));
    }
    typedValues.Add(GetParameterTypedValue(criteria, criteriaQuery)); 

    return typedValues.ToArray();
  }

  public TypedValue GetParameterTypedValue(ICriteria criteria, ICriteriaQuery criteriaQuery)
  {
    var matchValue = _value.ToString();
    if (_projection != null)
    {
      return CriterionUtil.GetTypedValues(criteriaQuery, criteria, _projection, null, matchValue).Single();
    }
    return new TypedValue(NHibernateUtil.String, _value.ToString(), EntityMode.Poco);
  }

  public override IProjection[] GetProjections()
  {
    if (_projection != null)
    {
      return new [] { _projection };
    }
    return null;
  }

  public override string ToString()
  {
    return " freetext(" + (_projection ?? (object)_propertyName) + "," + _value + ")";
  }
}

ProfileAttribute for MvcMiniProfiler

I’ve been using the MvcMiniProfiler quite a bit lately.  I put it in production with Acturent and I’ve contributed a bit to the project.  With Acturent, I came up with a simple ActionFilterAttribute that I’m using to auto inject the profiler to all actions in the application.  Rather than going through and specifically adding @MvcMiniProfiler.MiniProfiler.RenderIncludes() to each view, I just slap the following attribute on my base controller class:

public class ProfileAttribute : ActionFilterAttribute{
  public override void OnResultExecuted(ResultExecutedContext filterContext) {
    base.OnResultExecuted(filterContext);
    if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest()) return;
    var session = ObjectFactory.Container.GetInstance<IUserSession>();
    if (session != null) {
      var user = session.GetCurrentUser();
      if (user == null || !user.IsAdmin) return;

      var includes = MiniProfiler.RenderIncludes().ToString();
      using (var writer = new StreamWriter(filterContext.HttpContext.Response.OutputStream)) {
        writer.Write(includes);
      }
    }
  }
}

Obviously it will need a bit of tweaking if you implement it in your app.  Specifically, the user validation code should be swapped out with whatever logic you want to use to determine who sees the profile information.

Using pjax with ASP.Net MVC3

I was recently introduced to the pjax project and wondered how hard it would be to use it with asp.net.  It turns out that it takes next to no effort to have a basic asp.net mvc3 razor application support pjax.

Overview

pjax uses ajax to reload a portion of your page.  This is nothing new, but the “p” part of pjax stands for pushState.  PushState is a new feature of Html5 that allows you to modify browser history, without messing around with hash values.  So pushState gives you the speed boost of using ajax to update just part of your page, while offering a traditional experience for browsers like IE.  According to caniuse.com, Firefox 4+, Safari 5+, Chrome 8+, iOS 4+, and Android 2.2+ all support pushState.

Demo

The github home for the jQuery plugin for pjax has an overview of available options and usage.  The project also has a demo hosted on heroku that will give you an idea of how pjax works and some ideas for how you can use it in your application(s).

My version using Asp.Net MVC3

While my version may not be as sexy as the Ruby example, it’s simple and allows you to still use content sections for things like javascript.  I just check for the X-PJAX header in the _ViewStart.cshtml, where my layout is specified for the views.  If the X-PJAX header is specified, then the views should use a “chrome-less” layout.  Otherwise, they should use the normal layout.

The _ViewStart.cshtml file looks like:

@{
  if (Request.Headers["X-PJAX"] != null) {
    Layout = "~/Views/Shared/_PjaxLayout.cshtml";
  } else {
    Layout = "~/Views/Shared/_Layout.cshtml";
  }
}

My _PjaxLayout.cshtml layout file is very basic and just contains a tag for the page title and the content body section:

<title>@ViewBag.Title</title>
@RenderBody()

Additional thoughts

If you have javascript that needs to run on the page, you could easily add @RenderSection(“Script”, false) after @RenderBody().  Just keep in mind that the pjax plugin only updates one container on the page.  So if you have multiple html content sections that need updating, you would need to wrap them in a container that could be updated in one call.

Download

If you’re interested, feel free to take a look at the asp.net mvc3 pjax demo project I created.

NHibernate QueryOver Support For OrderBy Random

I had a need to get random records from the database, so I came up with this extension to the NHibernate QueryOver api. It is for Microsoft SQL Server, but it shouldn’t take much effort to port it to other database flavors.

public static class NHibernateExtensions
{
  public static IQueryOver<TRoot, TSubType> OrderByRandom<TRoot, TSubType>(this IQueryOver<TRoot, TSubType> query)
  {
    query.UnderlyingCriteria.AddOrder(new RandomOrder());
    return query;
  }
}

public class RandomOrder : Order
{
  public RandomOrder() : base("", true)
  {
  }

  public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery)
  {
    return new SqlString("newid()");
  }
}