MvcMiniProfiler and NHibernate: Take 3

[UPDATE see comments below - avoid this for time being ... batches were working but were not profiling, apologies ...]

[UPDATE 2 - my clone on google code has been updated and batched commands are now profiling (see comments)]

Time for a another NHibernate/MvcMiniProfiler update ...

Although the RealProxy solution for getting the MiniProfiler to work with NHibernate batching and SqlServer showed initial promise, people were still running into problems casting the transparent proxy.

Some people have had success by modifying and recompiling the NHibernate source, but this wasn't something I wanted to do. Others had been duplicating some code from NHibernate in their projects - the cleanest solution I've seen so far was the one that Harry McIntyre describes here -

http://www.adverseconditionals.com/2011/08/fixing-miniprofiler-with-nhibernat...

(Thanks to Harry and "Nick" that his fix was based on)

It duplicates the SqlClientBatchingBatcher from the NHibernate source - with a simple modification that should be easy to keep up-to-date with future NHibernate releases.

This solution also allows us to drop RealProxy and revert to the original wrapping ProfiledDbCommand however I chose to derive a new ProfiledSqlCommand that exposes the wrapped DbCommand, which means we don't need to clone the command and parameters.

For reference my change to SqlClientBatchingBatcher was in "AddToBatch", changing this line -

currentBatch.Append((System.Data.SqlClient.SqlCommand) batchUpdate);

to

if (batchUpdate is ProfiledSqlCommand)
    {
        currentBatch.Append(((ProfiledSqlCommand)batchUpdate).SqlCommand);
    }
    else
    {
        currentBatch.Append((System.Data.SqlClient.SqlCommand)batchUpdate);
    }

I've cloned the mvc-mini-profiler on Google Code and added a new MvcMiniProfiler.NHibernate project - you can see my current version here -

http://code.google.com/r/roberthmilne-mvc-mini-profiler/source/browse/#hg%2FMvcMiniProfiler.NHibernate

Would love to hear how other people get on with this, maybe it could be the starting point for an MvcMiniProfiler.NHibernate nuget package?

Using WebActivator to register Elmah

Since David Ebbo released WebActivator last year, my web.config files have been getting a lot neater. In fact I realised the other day that the only remaining HttpModules/HttpHandlers in one web.config were the ones for Elmah and I wondered if I could use WebActivator to hook them up in my MVC3 project ...

Registering the Elmah ErrorLogModule was a piece of cake using the DynamicModuleUtility, however the HttpHandler proved much trickier as there is no equivalent DynamicHandlerUtility. My solved this by registering a new route and creating an ElmahRouteHander which simply gets the HttpHandler from the the original ErrorLogPageFactory. The trick in getting this to work was to extract the pathInfo from RouteData and rewriting the request (Elmah uses PathInfo which is blank otherwise).

The full gist below - I suppose this could become the starting point for an new Elmah.Mvc Nuget package - comments and opinions welcome.

[updated gist after initial posting to fix routing issue]

 

RealProxy Performance

from @samsaffron

how much perf does this leak? can you plug it into the dapper perf tests?

Sure!

These test results do not include MiniProfiler, they simply shows the overhead of using RealProxy for the DbCommand (standard performance tests over 500 iterations - see http://code.google.com/p/dapper-dot-net/ for comparison)

  Standard(ms) RealProxy(ms)
NHibernate Session.Get 238 331 +39%
NHibernate SQL 248 417 +68%
NHibernate HQL 256 431 +68%
NHibernate Criteria 330 507 +54%
NHibernate LINQ 1359 1520 +12%

(after comparing these times to the ones on the Dapper home page I think I need a new PC)

The overhead is probably higher than I was expecting, however in practice it's certainly not noticable. My current implementation of the profiled database driver only proxies the DbCommand if the MiniProfiler has a current session, so this overhead will only exist when the profiler is running.

MvcMiniProfiler and NHibernate: Progress

@samsaffron tweeted -

nice one, how is this working with nhibernate? should we pull this in to core?

Couldn't really answer this in 140 characters, so here goes ...

How is this working with nhibernate?

This is working very nicely for me, timings and Sql formatting look good - the only minor issue is stack trace which can look a bit funky (I've had to increase the MaxStackLength setting to 1024), here's an example -

Invoke PrivateInvoke ExecuteReader GetReader DoList ListIgnoreQueryCache List GetResultsFrom GetResults get_Results GetCurrentResult <GetFutureValue>b__0 get_Value ToPagedList GetAllActive ListAccounts

and another (this was select N+1 (my bad), lazy loading via Linq expression and Json serialization!)

Invoke PrivateInvoke ExecuteReader GetResultSet DoQuery DoQueryAndInitializeNonLazyCollections LoadCollection Initialize Initialize OnInitializeCollection InitializeCollection Initialize Read System.Collections.Generic.IEnumerable<T>.GetEnumerator <ListAccounts>b__0 <ForJson>b__0 SerializeEnumerable SerializeValueInternal SerializeValue SerializeCustomObject SerializeValueInternal SerializeValue Serialize Serialize Serialize

I've not seen enough patterns yet to know if this could be tidied up - it might be possible for a future version of the MiniProfiler to have an IStackTraceSnippetFormatter that could sanitise the output (I will experiment with this)

[UPDATE: MiniProfiler already had a solution for this, the following exlcudes tidy up the stack trace nicely -

MiniProfiler.Settings.ExcludeAssembly("mscorlib");
MiniProfiler.Settings.ExcludeAssembly("NHibernate");
MiniProfiler.Settings.ExcludeAssembly("System.Web.Extensions");

MiniProfiler.Settings.ExcludeType("DbCommandProxy");

]

Should we pull this in to core?

It's possibly too early to say - the project I'm testing this with at the moment is pretty simple, very clean, I'm using NHibernate 3.2 (still in beta) and I've only tested this with Sql Server 2008.

The next step will be to pull this into a larger production system that uses NHibernate 3.0 GA and see if anything crops up. I would also like to test this with PostgreSQL to verify that the approach will hold up with other databases.

The DbCommandProxy is database agnostic so once a few more people have tested this and verified it doesn't cause any problems then I don't see any reason why this couldn't be pulled into the core. However I don't think that the 12 line profiled client driver class should be in the core (it would require NHibernate as a dependency)

I'm loving the MiniProfiler, thanks again to the SO guys for open sourcing this.

MvcMiniProfiler and NHibernate: Take 2 - Batching support

[UPDATE: Thanks to Sam for the comment - data reader now intercepted and wrapped, gist updated]

My previous solution for getting NHibernate working with MvcMiniProfiler had one problem, it didn't work with batching.

RealProxy was mentioned as a possible solution in the issues forum - see http://code.google.com/p/mvc-mini-profiler/issues/detail?id=29&can=1

The following code should be viewed as experimental, I have never used RealProxy before and I may be doing something really dumb here - however this is working well in my application and profiling now works with batching.

The solution is similar to before, I'm creating a new NHibernate client driver. However this time I'm not using any of the existing profiled wrapper classes. I'm creating a transparent proxy for SqlCommand, intercepting calls to ExecuteNonQuery/ExecuteReader/ExecuteScalar and making calls to the IDbProfiler.

Here's the gist, comments appreciated -

MvcMiniProfiler and NHibernate

MvcMiniProfiler is the latest open source offering from Stack Exchange - more at http://code.google.com/p/mvc-mini-profiler/

There's currently no information about getting the database profiling working with NHibernate - however I was able to get this working by creating a new client driver as follows -

I'm using NHibernate 3.2 Beta 1 so this was configured as follows -

This hasn't been used in a production tested but initial tests are working well.

 

Minifying Javascript and CSS Inline using Spark Bindings

After my earlier post about minifying javascript and CSS inline using Spark partials, I got the following tweet from Louis DeJardin (#IMMD)

nice! you might also be able to use a binding for that instead of a partial... same net result, of course...

Looking at the documentation Louis recently added for the bindings (http://sparkviewengine.com/documentation/bindings) I noticed one example was binding the <a> tag … I couldn’t bind the <script> and <style> tags … could I?

Bindings.xml

Notes

  • See documentation for explanations for the 'child::*' and '@*' terms
  • I couldn’t get the 'child::*' term to work properly with the Spark 1.1 binaries and had to get the latest source from http://github.com/loudej/spark

Binding Helpers/Extensions

Example

Our previous example now looks this this -

UPDATED: Updated to incorporate attribute based cache directive suggested by Louis

and produces the following output at runtime (when no debugger attached)

Filed under  //   MVC   Spark  

Minify Update – Debugging and Caching

This is a follow-up to my last post which described using Spark partial views to minify CSS and Javascript inline.

I thought it would be interesting to see if I could disable this during debugging and also cache the results -

Updated _minifyJS.spark

Updated _minifyCSS.spark

Filed under  //   MVC   Spark  

Minifying Javascript and CSS Inline with Spark Partials

UPDATE: Also see the follow-up post which adds debug and caching support.

UPDATE 2: Another even better way to do this using spark bindings

This was one of my favourite tricks with Spark – I though it was about time I updated it for Spark 1.1, Visual Studio 2010 and SparkSense.

Background

Recently I’ve been using Evan Nagle’s wonderful VS2010 extension Chirpy for combining and minifying my javascript and css. (http://chirpy.codeplex.com/ thanks Evan!) However I like keeping one-off bits of CSS and Javascript on the relevant page. Wouldn’t it be nice if you could minify those too?

Came up with a solution in Spark 1.0, MVC 1, VS2008 and using an earlier version of the Microsoft Ajax Minifier that worked pretty well – but now that Robert Greyling has released an early preview of SparkSense (http://blog.robertgreyling.com/ thanks Robert!) I thought I’d see if I could make it better.

Minifying Javascript

Here’s an simple example -

Couple of things

  • the script tag is there with if=”false” so that we get jQuery intellisense without rendering the actual tag on the page
  • note we are using the excellent T4MVC (http://mvccontrib.codeplex.com/releases/view/41582 – thanks David Ebbo!)
  • the <minifyJS> is our Spark partial view that is going to do the minification

So what is this <minifyJS>? – it’s simply a Spark partial, and there’s hardly anything to it -

This just renders the contents of our <minifyJS> tag to a local variable and then uses the Microsoft Ajax Minifier V4 (http://aspnet.codeplex.com/releases/view/40584) – all you need to do is reference AjaxMin.dll in your project.

Lets see what that looks like in VS2010 (with SparkSense v0.1 installed)

Minjs

Looking good – VS is ignoring our <minifyJS> tags, but still showing our syntax highlighting and intellisense including jQuery.

Loading the page now gives us -

Minifying CSS

Version 4 of the Microsoft Ajax Minifier added CSS, so lets see if we can do that too -

… and our _minifyCSS.spark -

VS2010 syntax highlighting and intellisense.

Mincss

And it outputs …

What about whitespace?

I don’t normally worry too much about leading whitespace (although I hate trailing whitespace) – however if you have a large table or are rendering out a tree/sitemap with nested lists, the leading whitespace can really add up. We can use Spark partials to help us here too -

with the following partial -

 

This will remove all leading and trailing whitespace for each line, giving us -

Summary

I wish there was a way to do this with the default view engine (or even with the upcoming Razor) - but it's yet another reason to love the Spark View Engine (thanks Louis DeJardin!)

Filed under  //   MVC   Spark  

Switching between Http and Https automatically with ASP.NET MVC

Although MVC 2 added the RequireHttps attribute, there is no corresponding RequireHttp attribute. Now it's not that hard to write your own RequireHttp implementation, but I don't really want to have to decorate all the actions in my controllers. Additionally I'd like to be able to specify a default in my controller and then override it on specific actions. I also want to be able to override an action so it ignores the controller and allows both. It turned out to be a lot simpler than imagined.

(I don't really like the attribute name, even if it is technically correct, can anyone think of a better one?)

This lets us use it as follows -

The only thing to note with this approach is that a redirect from https to http might cause warning messages on older browsers -"You are about to be redirected to a connection that is not secure" - now, when I say older browsers, I mean IE 6 (and earlier)...

Constructive criticism welcome ;)

Filed under  //   MVC  

About