NHibernate, Castle IOC and MVC.NET 2 running in medium trust on shared hosting

Saturday, November 28th, 2009

This has caused me a lot of pain today so I thought that I would share my findings!

If you intend to publish your site to shared hosting and they are restricting you to a Medium trust security policy (which is expected really on shared hosting) you need to have assemblies that work properly!

After finding the issue the first thing I did was to get a dev environment that replicated the problem. The easiest way to do this is to set the trust level in the web.config. You can do this by adding this within the system.web  element:

<system.web>
<trust level=”Medium”/>

…other tastey elements…..

</system.web>

In the future I will set this before I start programming anything - probably good practice when you know you will be deploying to a medium trust environment but I will put that down to a lesson learnt!

After that you need to build Castle from source with a few additional parameters to make it run in medium trust. To do this you need to check it out from SVN. I had a few problems here too with SVN externals. I ended up getting the latest version of tortoise and checking it out on a Windows 7 VM I had running.
Check it out from here: http://svn.castleproject.org:8080/svn/castle/trunk/

Once fully checked out, open a cmd promt and navigate to the the root of the checked out directory. run this command:
build.cmd -D:assembly.allow-partially-trusted-callers=true release quick build

Watch the window for any errors and please read the error messages if you get any. I got one in relation to not having the .NET 2.0 SDK installed, so guess what - I installed it and tried again and it worked!

OK great now we have some assemblies that will run under medium trust. Copy these over the old versions and make sure you perform a clean build. Thats Castle sorted right? WRONG! It still won’t work.

I then had an issue with Castle.Service.Transations. Read this for more information (http://stackoverflow.com/questions/1038914/using-castle-windsor-and-the-nhibernate-facility-on-shared-hosting). OK no probs got that sorted by registering it in my container:

container.Register(Component
.For(typeof (IActivityManager))
.ImplementedBy(typeof (TLSActivityManager)));

OK we are still not there - a couple more things to do in the web.config. You need to add the requirePermission=”false” attribute the the castel section:

<section name=”castle” requirePermission=”false” type=”Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor”/>

I also disabled the NHibernate reflection optimiser:

<item key=”reflection-optimizer”>false</item>

OK almost there - the app will now run. Next was the problem of URL’s and the fact I was not allowed a wild card mapping - fine - no probs, lets update the routing. I changed my routing to the following:

routes.MapRoute(
"Default",
"{controller}.aspx/{action}/{id}",
new {controller = "Home", action = "Index", id = ""},
new[] {”ANAMESPACE.Core.Controllers”});

Yay! That works! There is only one more problem. If I go to / then it can’t find a route regardless of the default file settings. So a bit of a workaround was to add another route after the usual default:

routes.MapRoute(
"",
new { controller = "Home", action = "Index", id = "" },
new[] { “ANAMESPACE.Core.Controllers” });

This feels very wrong and I don’t like it! There must be a better way.

Anyway - screw you shared hosting and medium trust!

Castle ISessionFactory can be resolved outside of a web request

Wednesday, July 15th, 2009

I found this very useful today. I have a Quatz Job running that requires access to a repository. This repository is usually resolved by castle like so:

var repository = Registry.Get<MyRepository>();

In the case I have I cannot do this as ‘MyRepository’ depends on having an ISessionManger injecting into it but in this context one does not exists. What I found out though (thanks to Thom) was that I can simply ask the container for an ISessionFactory like so:

var sessionFactory = Registry.Get<ISessionFactory>();

Now I can create a class that implements ISessionManager and instantiate my repository with this - top stuff!

Now I have found this I will be changing how my integration tests work!

testing sending emails .NET

Friday, July 10th, 2009

At first I thought this may be tricky but as it turns out I am not the only one ever to have this problem!

First of all you can try and use the SpecificPickupDirectory. This tells the smtp client to simply drop the message into a desegnated directory:

http://dotnettipoftheday.org/tips/smtp-delivery-method-SpecifiedPickupDirectory.aspx

<system.net>

<mailSettings>

<smtp deliveryMethod=”SpecifiedPickupDirectory”>

<specifiedPickupDirectory pickupDirectoryLocation=”c:\Test\” />

</smtp>

</mailSettings>

</system.net>


If that does not float your boat then you can take it a stage further:

http://haacked.com/archive/2006/05/30/ATestingMailServerForUnitTestingEmailFunctionality.aspx

Another useful tool is this: http://www.codeproject.com/KB/IP/despop3client.aspx

Code metrics in reflector for C#

Tuesday, June 9th, 2009

http://reflectoraddins.codeplex.com/Wiki/View.aspx?title=CodeMetrics

sqlite with nhibernate - a guide to getting it working

Wednesday, May 27th, 2009

I am currently working on a new project and I am going full on TDD and BDD (where appropriate). As I have been in a variety of different environments I want to be able to check out the project, run the tests and write some code. My integration tests rely on a database (currently proving that my nhibernate mappings are correct) and I did not want there to be a dependency on having a database running so I wanted to use sqlite.

Here is what I did:

Download sqlite:

http://sourceforge.net/projects/sqlite-dotnet2

Get an sqlite GUI admin tool:

http://sqliteadmin.orbmu2k.de/

Create a database to connect to.

Change you nhibernate config file:

<?xml version="1.0" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.provider">
NHibernate.Connection.DriverConnectionProvider
</property>
<property name="dialect">
NHibernate.Dialect.SQLiteDialect
</property>
<property name="connection.driver_class">
NHibernate.Driver.SQLite20Driver
</property>

<property name="connection.connection_string">
Data Source=directory-in-your-test-assembly\your-database.s3db
</property>

<property name="query.substitutions">true=1;false=0</property>

<mapping assembly="YourAssembly" />

</session-factory>
</hibernate-configuration>

Notice that I have used the SQLite20Driver instead of SQLiteDriver (it won’t work otherwise!)

Don’t forget to make sure that your db is copied to your output directory.

I will expand upon this post tomorrow when I have more time!

New release of the ajax control toolkit

Thursday, May 14th, 2009

http://weblogs.asp.net/bleroy/archive/2009/05/13/new-release-of-the-ajax-control-toolkit.aspx

NAct - a .NET port of Jbehave

Wednesday, May 13th, 2009

NAct is now on google code. Built by Tim Wilde from TechnoPhobia (my place of work).

Super duper:

http://code.google.com/p/nact

Quartz.NET - open source job scheduling system

Wednesday, May 13th, 2009

How have I missed this for so long!

http://quartznet.sourceforge.net/

Lucene.NET Did you mean? - easy how to…

Sunday, May 10th, 2009

This is actually very simple to do and you can get it done in about 20 mins! I did a bit of Googling and could not find much about it so I thought that I should share my findings.

First of all you need an additional assembly called SpellChecker.Net. This assembly is a part of lucene.net and can be found in the contrib directory. I checked it out from SVN here: https://svn.apache.org/repos/asf/incubator/lucene.net/trunk/C#/contrib/SpellChecker.Net

Just open the solution and then build it in release configuration. That’s it - you now have the SpellChecker dll you need.

Now all you have to do is add a reference to this in the project that you have lucene etc (you get what I am on about I am sure).

Ok so now for the fun bit - actually using it! This is simpler than you might expect. In my case I added it to my SearchEngine class. This may be the right or wrong thing to do but for now it felt right - I perform a search on the engine - why not ask it for the suggestions too?

Ok so here is the code:
private void createSuggestionList()
{
var spellChecker = new SpellChecker.Net.Search.Spell.SpellChecker(_searcher.Reader.Directory());
spellChecker.IndexDictionary(new LuceneDictionary(_searcher.Reader, "title"));
_suggestions = spellChecker.SuggestSimilar(_originalSearchTerm, 5);
}

Ok so let me explain:

  • Firstly we create an instance of the spell checker and pass in a directory. ‘_searcher’ is an instance of ‘IndexSearcher’ (you should be aware of one of these are if you are using Lucene)
  • Then we tell the spellChecker which index to read and which field to gather its spelling suggestions from
  • All we have to do now is grab an array of strings from a search term

I told you it was easy - enjoy….

The remote server returned an error: (417) Expectation Failed

Friday, May 1st, 2009

This is a really obscure error so I thought that I would share the solution.

This is caused by an additional header ‘HTTP header “Expect: 100-Continue”‘ being added to the request. The solution is to set the following:

System.Net.ServicePointManager.Expect100Continue = false;

Great - what a pile…