The Software Artist | Code is a form of art.

TAG | ASP.NET MVC

UPDATE: The instructions for building S#arp were updated shortly after I published this post. See below for more.

My previous post on running S#arpArchitecture 1.0 in medium trust seemed to be helpful to a few, so here are instructions on getting the latest build of S#arp (1.5.2 at the time of writing) running in medium trust as well. The platforms that S#arp depends upon have matured a bit since last time and some of the assemblies already have the AllowPartiallyTrustedCallers attribute, so running in medium trust is much easier now. See the 1.0 post for a little more background info.

These instructions are organized as follows:

  1. The dependency project/component that we must rebuild
  2. Where to get the source
  3. Which previously built assemblies to copy to this project’s lib/dependency folder, if any
  4. Any changes you must make to the code, solution/project files, or build files
  5. How to build the component
  6. Where the build output is located, and the specific assemblies we are interested in. You may want to create a common lib directory to copy all of these to because you will need to keep track of them. I’ll only mention the assemblies here, but you may also want to copy the xml documentation files (which are named the same as the assemblies but with the .xml extension) as well.

Castle Core 1.2

  1. Get the source from: http://github.com/castleproject/Castle.Core/tree/1-2-stable
  2. Build the project with the following parameter: -D:assembly.allow-partially-trusted-callers=true. Here is the command line I use:
        nant -D:assembly.allow-partially-trusted-callers=true -D:common.testrunner.enabled=false -D:project.config=release
        
  3. The output is located in build\net-3.5\release. Copy these assemblies to your lib directory:
    • Castle.Core.dll

Castle InversionOfControl 2.1

  1. Get the source from: http://github.com/castleproject/Castle.InversionOfControl/tree/2-1-stable
  2. Copy these assemblies to lib\net-3.5:
    • Castle.Core.dll
  3. Build with the same command as for Castle Core:
        nant -D:assembly.allow-partially-trusted-callers=true -D:common.testrunner.enabled=false -D:project.config=release
        
  4. The output is located in build\net-3.5\release. Copy these assemblies to your lib directory:
    • Castle.MicroKernel.dll
    • Castle.Windsor.dll

Common Service Locator Windsor Adapter

  1. Get the source from: http://commonservicelocator.codeplex.com/wikipage?title=Castle%20Windsor%20Adapter
  2. Copy these assemblies to sharedlibs:
    • Castle.Core.dll
    • Castle.DynamicProxy2.dll (from your SharpArch bin directory)
    • Castle.MicroKernel.dll
    • Castle.Windsor.dll
  3. Add the following lines to CommonServiceLocator.WindsorAdapter\Properties\AssemblyInfo.cs:
      using System.Security;
      [assembly: AllowPartiallyTrustedCallers]
      
  4. Build the project, either from Visual Studio or with the following command line:
      msbuild commonservicelocator.windsoradapter.csproj /t:Rebuild /p:Configuration=Release
      
  5. The output is located in CommonServiceLocator.WindsorAdapter\bin\release. Copy these assemblies to your lib directory:
    • CommonServiceLocator.WindsorAdapter.dll

MvcFutures (Microsoft.Web.Mvc.dll)

  1. Get the ASP.NET MVC 2 source from: http://aspnet.codeplex.com/releases/view/41742
  2. Open the MvcDev.sln solution in Visual Studio, and in the MvcFutures project:
    1. Delete the existing System.Web.Mvc reference (which is to the local System.Web.Mvc project) and add a reference to the System.Web.Mvc version 2 assembly in your GAC
    2. Add the following lines to Propertes\AssemblyInfo.cs:
            using System.Security;
            [assembly: AllowPartiallyTrustedCallers]
            
    3. Build the MvcFutures project. You can also build from the command line:
      msbuild MvcFutures.csproj /t:Rebuild /p:Configuration=Release
  3. The output is located in bin\release. Copy these assemblies to your lib directory:
    • Microsoft.Web.Mvc.dll

MvcContrib

  1. Get the source from: http://mvccontrib.codeplex.com/SourceControl/list/changesets
  2. Copy these assemblies to bin\castle:
    • Castle.Core.dll
    • Castle.MicroKernel.dll
    • Castle.Windsor.dll
  3. Copy Microsoft.Web.Mvc.dll to bin\aspnetmvc
  4. Open MVCContrib.sln in Visual Studio and in the MvcContrib.Castle and MvcContrib.FluentHtml projects, add an AssemblyInfo.cs file with the following two lines:
          using System.Security;
          [assembly: AllowPartiallyTrustedCallers]
          
  5. Build the solution in Visual Studio or with the following command line:
    nant.exe -buildfile:nant.build -D:project.config=release -D:runtests=false
  6. The output is located in build\net-3.5.win32-MVCContrib-release. Copy these assemblies to your lib directory:
    • MvcContrib.dll
    • MvcContrib.FluentHtml.dll
    • MvcContrib.Castle.dll

Inflector.Net

  1. Get the source from: http://andrewpeters.net/inflectornet/. This site appears to be down at the moment so I’ve uploaded Inflector.Net to my site, you can download it from http://paulwideman.com/inflectornet.zip.
  2. Open Inflector.Net.sln and add the usual two lines to Propertes\AssemblyInfo.cs:
          using System.Security;
          [assembly: AllowPartiallyTrustedCallers]
          

    Then build the solution in release config.

  3. The output is located in Inflector.Net/bin/release. Copy Inflector.Net.dll to your lib directory.

S#arp

  1. Get the latest source from: http://github.com/codai/Sharp-Architecture
  2. Copy all assemblies from your lib directory to bin.
  3. Edit the SharpArch.build file so that it adds the AllowPartiallyTrustedCallers attribute to the automatically generated CommonAssemblyInfo.cs file, by adding the two highlighted lines below:
        <target name="version" description="Generate AssemblyInfo">
          <property name="version.build" value="${build.number}" if="${property::exists('build.number')}"/>
          <property name="version.revision" value="${build.vcs.number.1}" if="${property::exists('build.vcs.number.1')}" />
    
          <echo message="Marking build with version ${project.fullversion}" />
          <delete file="${solution.dir}/CommonAssemblyInfo.cs" failonerror="false"/>
          <asminfo output="${solution.dir}/CommonAssemblyInfo.cs" language="CSharp">
            <imports>
              <import namespace="System.Reflection" />
              <import namespace="System.Runtime.InteropServices" />
              <import namespace="System.Security" />
            </imports>
            <attributes>
              <attribute type="ComVisibleAttribute" value="false" />
              <attribute type="AssemblyVersionAttribute" value="${project.fullversion}" />
              <attribute type="AssemblyFileVersionAttribute" value="${project.fullversion}" />
              <attribute type="AssemblyInformationalVersionAttribute" value="${project.fullversion}" />
              <attribute type="AssemblyCopyrightAttribute" value="Copyright © ${company.name} ${datetime::get-year(datetime::now())}" />
              <attribute type="AssemblyCompanyAttribute" value="${company.name}" />
              <attribute type="AssemblyConfigurationAttribute" value="${project.config}" />
              <attribute type="AssemblyTrademarkAttribute" value="" />
              <attribute type="AssemblyCultureAttribute" value="" />
              <attribute asis="true" type="AllowPartiallyTrustedCallersAttribute" />
            </attributes>
            <references>
              <include name="System.dll" />
            </references>
          </asminfo>
        </target>
        
  4. UPDATE: There seems to be a bug in the release build configuration in the latest S#arp source. The merged SharpArch.dll assembly does not contain the content from all of the SharpArch projects. To fix this, open SharpArch.sln in Visual Studio and update the properties for each project to change the output path for the release configuration to “bin\Release\”.
  5. Build S#arp with this command line:
    NAnt.exe -buildfile:SharpArch.build -D:project.config=release
  6. The output is located in build. Copy SharpArch.dll to your lib directory.

From here, the steps are the same as with 1.0:

Now we’ve got a version of SharpArch and all its dependencies that will run in medium trust. Even if you have no interest in running the Northwind sample in medium trust, there are a few things we must do to a web app built with the SharpArch project template to enable it to run in medium trust. So I believe these instructions are applicable to any web app built with the SharpArch project template.

Northwind Sample

  1. Copy all of the newly build assemblies from your lib directory to the SharpArch\bin directory. The Northwind project references these dlls from there.
  2. Edit src\NorthwindSample\CommonAssemblyInfo.cs to add the AllowPartiallyTrustedCallers attribute:
    using System.Security;
    [assembly: AllowPartiallyTrustedCallers]
    
  3. Open Northwind.sln in VS2008
  4. We have to make a few changes to the NHibernate configuration so that NHibernate will run properly in medium trust. One of these (reflection-optimizer) requires us to move the NH config out of its own file and into web.config. To move the config into web.config, in the Northwind.Web project:
    1. Add a config section declaration for the NH config section, I put mine right after the log4net section declaration:
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" requirePermission="false"/>
        <section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" requirePermission="false" />
        
    2. Copy the <hibernate-configuration> section and all of its contents from NHibernate.config to somewhere in web.config, I put mine right above the log4net section.
    3. Open Global.asax.cs, go to the InitializeNHibernateSession() method, and remove the last parameter in the call to NHibernateSession.Init() to tell NHibernate to get its config from web.config.
  5. Update the NH configuration info in web.config for use in medium trust:
    1. Remove the adonet.batch_size property, NHibernate update batching does not work in medium trust
    2. Add <reflection-optimizer use="false" /> as a child of <hibernate-configuration>. The reflection optimizer requires some reflection permissions that aren’t available in medium trust. Turning the reflection optimizer off will cause a performance decrease overall, although you may see a performance boost during app startup. See the NHibernate documentation here for more info.
    3. As per the SharpArch docs, add the current_session_context_class property with value managed_web. In my testing I didn’t find this necessary, but assuming the docs are up to date then it is their guidance to add it. You can see the NHibernate documentation here for more on this property.

    My final config section in web.config is as follows:

    <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
      <reflection-optimizer use="false" />
      <session-factory>
        <property name="connection.connection_string">Data Source=your_server;Database=Northwind;UID=username;pwd=password;</property>
        <property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
        <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
        <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
        <property name="show_sql">false</property>
        <property name="connection.release_mode">auto</property>
        <property name="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
        <property name="current_session_context_class">managed_web</property>
    
        <!-- Mapping assemblies -->
        <!-- Can't map it for Fluent NHibernate here; instead, load the mapping assembly in Global.asax.cs.
        If you're still using HBMs, you can use the mapping here or pass the assembly via Global.asax.cs
        as well, just like you can do with the Fluent NHibernate assembly(s). -->
        <!-- mapping assembly="Northwind.Data" -->
      </session-factory>
    </hibernate-configuration>
    
  6. Set the app to use medium trust by adding <trust level="Medium" /> to the system.web section.
  7. Don’t forget to update the NH config with your Northwind database info.
  8. If you want to make use of the WCF part of the Northwind sample app, you’ll need to manually add the AllowPartiallyTrustedCallers attribute to the Northwind.Wcf\Properties\AssemblyInfo.cs file.
  9. Set Northwind.Web as the startup project, rebuild and run.

That’s it, the Northwind sample app should now run successfully in medium trust.

· · ·

Dec/09

28

Building ClubPool – Intro

I’m a member of a local billiards league, and while we’re pretty much all computer nerds, a few years ago I volunteered to create a website to manage our league. It’s standard stuff – allows users to log in, view their past matches, see their upcoming opponent, view the yearly schedule of matches, etc. Nothing about it is remotely complicated, but when I was writing it years ago I didn’t have much experience with ASP.NET, no experience with any type of ORM, Ajax framework, or pretty much anything else that constitutes today’s modern web applications. I also had to complete it in a hurry because I started roughly a month before our next league season started. Anyway, all of that is to say that the current website for our pool league is in dire need of a rewrite.

So, I’m in the process of creating an entirely new website for our league. The new website will be based on ASP.NET MVC, using S#arpArchitecture in particular. I’ll also borrow ideas from the excellent Who Can Help Me? showcase application for SharpArch. SharpArch itself is overkill for this small application, but I want to use this as a learning experience so I’m ok with dealing with the extra overhead. WCHM is even more advanced/complicated, so I’m only going to pluck a few interesting ideas from there (LinqRepository, for one).

I’m hosting the source for this new app at http://code.google.com/p/clubpool/, so it’s open source by default (not that anyone else would want this code, but they provide a free SVN server, so what the heck). I’m also using this experience as an excuse to start blogging, so I’m going to blog about it along the way. What I write will definitely NOT be a tutorial, since I’m learning along the way myself, but I’ll write about my decision making, interesting discoveries in ASP.NET MVC, SharpArch, etc. My hope is that someone out there will read these posts and offer their own insight and tell me where I’m going wrong. By blogging, I’m hoping to expose myself and this application to developers that are better than I am, so that they can help me. I’m certainly not doing it to instruct anyone else on how to write an application!

So that’s ClubPool. A relatively simple web app for managing my local billiards league, making use of these components:

Hopefully I’ll learn something along the way.

· · ·

As anyone with experience with medium trust will tell you, it can be a pain. It imposes certain security restrictions that a lot of code takes for granted, with reflection probably being the most common offender. SharpArchitecture is one such framework that doesn’t run in medium trust out of the box. This post describes how to get it and its Northwind sample application running in medium trust, using the SharpArchitecture 1.0 Q3 release.

First, a word of caution: I’m in the early stages of investigating SharpArch, especially in medium trust. One of the main changes we must make is to recompile all of the SharpArch dlls and dependencies with the AllowPartiallyTrustedCallers assembly attribute, so that they can be used in a medium trust environment. But simply adding this attribute to the assemblies doesn’t mean that the code in the assemblies is appropriate for use in a medium trust environment. So it’s possible that some of these components contain code which will raise SecurityPermission exceptions in medium trust. I only encountered one such issue with NHibernate.Validator, but deeper use of these components may uncover further issues. I will update this post with any new info as I begin building a real application running under medium trust with SharpArch and its dependencies.

The steps are pretty simple, the main thing we have to do is add the AllowPartiallyTrustedCallers attribute to all of the assemblies that are referenced by the Northwind sample app. One of the dependencies, NHibernate.Validator, will also require a small code change in order to run in medium trust properly. I’ve filed a bug against NHV for this problem, hopefully it will be fixed in a future version.

This is not a full step-by-step tutorial, these instructions assume you’re already familiar with pulling source from SVN servers, building projects with nant, etc. If you’re not familiar with these topics, there are many sources of info on the net that can explain them much better than I. So, let’s get started.

Castle

Several components from Castle are used by the Northwind app, both directly and indirectly, so we need to rebuild it first. Until recently, using NHibernate in medium trust required disabling lazy loading because Castle.DynamicProxy2 wouldn’t work properly in medium trust. Some recent fixes to DynamicProxy have remedied this, so we can now use NHibernate with lazy loading in medium trust. This is great, but unfortunately it means we must use a different version of the Castle components than what is included with SharpArch. This doesn’t cause a problem by itself, but we’ll have to rebuild basically all of SharpArch’s dependencies because of it.

The three Castle projects we must rebuild are Castle.Core, Castle.DynamicProxy2, and Castle.Windsor.

Castle.Core

  1. Pull the source from https://svn.castleproject.org/svn/castle/Core/trunk
  2. Build with the following command line parameter to add the AllowPartiallyTrustedCallers attribute to the assembly: -D:assembly.allow-partially-trusted-callers=true. Read the Castle docs for other parameters to the build script, you may also want to build without running tests and build the release config. Here is what I use to build a release build with AllowPartiallyTrustedCallers set, and to skip running the unit tests:
    nant -D:assembly.allow-partially-trusted-callers=true -D:common.testrunner.enabled=false -D:project.config=release
  3. The output files are located at build\net-3.5\release.

Castle.DynamicProxy

  1. Pull the source from https://svn.castleproject.org/svn/castle/DynamicProxy/trunk
  2. Copy the newly built Castle.Core.dll to \lib\net-3.5
  3. Build with nant. This project has the APTC attribute set already, so you do not need to provide it on the command line. You can use the same parameters as above to skip the tests and build a release build. The output files are located in build\net-3.5\release.

Castle.Windsor

  1. Pull the source from https://svn.castleproject.org/svn/castle/InversionOfControl/trunk
  2. Copy Castle.Core.dll and your new Castle.DynamicProxy2.dll to \lib\net-3.5
  3. Build with nant, providing the APTC command line argument. You can use the same command line as with Castle.Core, and the output files are once again located in build\net-3.5\release.

CommonServiceLocator.WindsorAdapter

Now that we’ve built Castle we can build the other dependencies that reference it, starting with the WindsorAdapter for the Common Service Locator from Microsoft’s Patterns & Practices group:

  1. Download the source from http://commonservicelocator.codeplex.com/wikipage?title=Castle%20Windsor%20Adapter
  2. Copy all of the newly built Castle dlls (Castle.Core.dll, Castle.DynamicProxy2.dll, Castle.MicroKernel.dll, and Castle.Windsor.dll) to the SharedLibs directory.
  3. Open the WindsorAdapter project in Visual Studio and edit the Properties\AssemblyInfo.cs file by adding the following two lines:
    using System.Security;
    [assembly: AllowPartiallyTrustedCallers]
    
  4. Build the project

NHibernate

  1. Pull the source from https://nhibernate.svn.sourceforge.net/svnroot/nhibernate/trunk
  2. Copy the newly built Castle.Core.dll and Castle.DynamicProxy2.dll to \nhibernate\lib\net\3.5
  3. Build with nant. This project already has the APTC attribute set, so you can use the same command line given for Castle.DynamicProxy. The output files will be located at build\<version>\bin\net-3.5. At the time of writing, the version is “NHibernate-3.0.0.Alpha1″.

NHibernate.Validator

  1. Pull the source from http://sourceforge.net/projects/nhcontrib/files/NHibernate.Validator. I use the 1.2.0 CR1 release: http://sourceforge.net/projects/nhcontrib/files/NHibernate.Validator/1.2.0%20CR1/NHibernate.Validator-1.2.0.CR1-src.zip/download.
  2. Copy the new Castle.Core.dll, Castle.DynamicProxy2.dll, and NHibernate.dll to lib.
  3. Edit NHibernate.Validator/Engine/InvalidMessageTransformer.cs, line 80 to:
        return validatorDef.Tags == null || validatorDef.Tags.Count == 0 ? new List<object>() : validatorDef.Tags;
        

    At some point NHV may be updated so that this step is not required.

  4. Build with nant: nant -D:skip.tests=true -D:project.config=release. The output files will be located in build\NHibernate.Validator-1.2.0.CR1\bin\net-3.5

FluentNHibernate

  1. Download the source from http://fluentnhibernate.org/downloads – I used the source download link to 1.0.0.600, which is the latest build at the time of writing: http://fluentnhibernate.org/downloads/fluentnhibernate-source-1.0.0.600.zip
  2. Copy the new Castle.Core.dll, Castle.DynamicProxy2.dll, NHibernate.ByteCode.Castle.dll, and NHibernate.dll to \tools\NHibernate
  3. Build src\FluentNHibernate.sln

Inflector.Net

  1. Download the source from http://andrewpeters.net/inflectornet/
  2. Open the solution in visual studio and add a new C# code file named AssemblyInfo.cs to the project, then add the following code to this file:
      using System.Security;
      [assembly: AllowPartiallyTrustedCallers]
      
  3. Build the Inflector.Net project

Microsoft.Web.Mvc

  1. The source for the Microsoft.Web.Mvc.dll assembly (MvcFutures) is part of the ASP.NET MVC source which can be downloaded at http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=24471
  2. Open the MvcFutures project at MVC-RTM\MVC\src\MvcFutures in Visual Studio and update Properties\AssemblyInfo.cs to add the AllowPartiallyTrustedCallers attribute with the following code:
      [assembly: AllowPartiallyTrustedCallers]
      
  3. The existing reference to System.Web.Mvc is a project reference to the MVC source in this download. Remove this reference and add a new reference to the released System.Web.Mvc, which should be in your GAC.
  4. Build the MvcFutures project
  5. The Microsoft.Web.Mvc.dll that SharpArch references is signed, so we must sign our new one. You can do so by executing the following in a Visual Studio command line. If you already have a key pair file, you can use that instead of creating a new one:

    sn -k myKey.snk
    ildasm /all /out=Microsoft.Web.Mvc.il Microsoft.Web.Mvc.dll
    ilasm /dll /key=sgKey.snk Microsoft.Web.Mvc.il

MvcContrib

  1. I use the MvcContrib 1.5 RC release which can be downloaded from http://mvccontrib.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=33777
  2. Copy the new Microsoft.Web.Mvc.dll to bin\aspnetmvc.
  3. Copy Castle.Core.dll, Castle.MicroKernel.dll, and Castle.Windsor.dll to bin\castle.
  4. The main MvcContrib project already has an AssemblyInfo file that includes the APTC attribute, but SharpArch includes two other assemblies from MvcContrib (MvcContrib.Castle and MvcContrib.FluentHtml) that do not have the APTC attribute set. MvcContrib.Castle is used by the Northwind sample app, while MvcContrib.FluentHtml is not, but we’ll go ahead and add the APTC attribute to both of these. Note that this is a good example of my cautionary note above. There may be code in these two projects which will fail in medium trust, although the Northwind sample app is able to use the WindsorControllerFactory from MvcContrib.Castle just fine. However, you may encounter problems if you attempt to use more from these two assemblies. Here’s how to add the APTC attribute to both:
    1. Open the MvcContrib solution in Visual Studio. The MvcContrib.FluentHtml project already has an AssemblyInfo file in its Properties folder. Open this file and add the following code:
        using System.Security;
        [assembly: AllowPartiallyTrustedCallers]
        
    2. Add an AssemblyInfo.cs file to the MvcContrib.Castle project and add the same code to it, then close Visual Studio.
  5. Build with nant: nant -D:project.config=release -D:runtests=false. The output location is build\net-3.5.win32-MVCContrib-release.

That’s it for the SharpArch dependencies, now we have to rebuild the SharpArch project itself.

SharpArchitecture

  1. Copy all newly built dependencies to bin:
    1. Castle.Core.dll
    2. Castle.DynamicProxy2.dll
    3. Castle.MicroKernel.dll
    4. Castle.Windsor.dll
    5. CommonServiceLocator.WindsorAdapter.dll
    6. FluentNHibernate.dll
    7. Inflector.Net.dll
    8. Microsoft.Web.Mvc.dll
    9. MvcContrib.Castle.dll
    10. MvcContrib.dll
    11. MvcContrib.FluentHtml.dll
    12. MvcContrib.TestHelper.dll
    13. NHibernate.ByteCode.Castle.dll
    14. NHibernate.dll
    15. NHibernate.Validator.dll
  2. Edit SharpArch.Tests/SharpArch.Web/CommonValidator/MvcValidationAdapterTests.cs to match latest NHibernate.Validator. The InvalidValue constructor requires a 6th argument in our newer version:
    invalidValues.Add(
        new ValidationResult(
            new InvalidValue("Message 1", typeof(TransactionAttribute), "Property1", null, null, null)));
    invalidValues.Add(
        new ValidationResult(
            new InvalidValue("Message 2", typeof(MvcValidationAdapter), "Property2", null, null, null)));
    invalidValues.Add(
        new ValidationResult(
            new InvalidValue("Message 3", GetType(), "Property3", null, null, null)));
    
  3. Edit the SharpArch.build file so that it adds the APTC to the automatically generated CommonAssemblyInfo.cs file, by adding the two highlighted lines below:
    <target name="version" description="Generate AssemblyInfo">
      <property name="version.build" value="${build.number}" if="${property::exists('build.number')}"/>
      <property name="version.revision" value="${build.vcs.number.1}" if="${property::exists('build.vcs.number.1')}" />
    
      <echo message="Marking build with version ${project.fullversion}" />
      <delete file="${solution.dir}/CommonAssemblyInfo.cs" failonerror="false"/>
      <asminfo output="${solution.dir}/CommonAssemblyInfo.cs" language="CSharp">
        <imports>
          <import namespace="System.Reflection" />
          <import namespace="System.Runtime.InteropServices" />
          <import namespace="System.Security" />
        </imports>
        <attributes>
          <attribute type="ComVisibleAttribute" value="false" />
          <attribute type="AssemblyVersionAttribute" value="${project.fullversion}" />
          <attribute type="AssemblyFileVersionAttribute" value="${project.fullversion}" />
          <attribute type="AssemblyInformationalVersionAttribute" value="${project.fullversion}" />
          <attribute type="AssemblyCopyrightAttribute" value="Copyright © ${company.name} ${datetime::get-year(datetime::now())}" />
          <attribute type="AssemblyCompanyAttribute" value="${company.name}" />
          <attribute type="AssemblyConfigurationAttribute" value="${project.config}" />
          <attribute type="AssemblyTrademarkAttribute" value="" />
          <attribute type="AssemblyCultureAttribute" value="" />
          <attribute asis="true" type="AllowPartiallyTrustedCallersAttribute" />
        </attributes>
        <references>
          <include name="System.dll" />
        </references>
      </asminfo>
    </target>
    
  4. Build with nant: nant -D:project.config=release

Now we’ve got a version of SharpArch and all its dependencies that will run in medium trust. Even if you have no interest in running the Northwind sample in medium trust, there are a few things we must do to a web app built with the SharpArch project template to enable it to run in medium trust. As such, I believe these instructions are applicable to any web app built with the SharpArch project template.

Northwind Sample

  1. Copy the newly built SharpArch*.dll files from the SharpArch\build directory to the SharpArch\bin directory. The Northwind project references these dlls from the SharpArch\bin directory.
  2. Edit src\NorthwindSample\CommonAssemblyInfo.cs to add the APTC attribute:
    using System.Security;
    [assembly: AllowPartiallyTrustedCallers]
    
  3. Open Northwind.sln in VS2008
  4. We have to make a few changes to the NHibernate configuration so that NHibernate will run properly in medium trust. One of these (reflection-optimizer) requires us to move the NH config out of its own file and into web.config. To move the config into web.config, in the Northwind.Web project:
    1. Add a config section declaration for the NH config section, I put mine right after the log4net section declaration:
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" requirePermission="false"/>
        <section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" requirePermission="false" />
        
    2. Copy the <hibernate-configuration> section and all of its contents from NHibernate.config to somewhere in web.config, I put mine right above the log4net section.
    3. Open Global.asax.cs, go to the InitializeNHibernateSession() method, and remove the last parameter in call to NHibernateSession.Init() to tell NHibernate to get its config from web.config.
  5. Update the NH configuration info in web.config for use in medium trust:
    1. Remove the adonet.batch_size property, NHibernate update batching does not work in medium trust
    2. Add <reflection-optimizer use="false" /> as a child of <hibernate-configuration>. The reflection optimizer requires some reflection permissions that aren’t available in medium trust. Turning the reflection optimizer off will cause a performance decrease overall, although you may see a performance boost during app startup. See the NHibernate documentation here for more info.
    3. As per the SharpArch docs, add the current_session_context_class property with value managed_web. In my testing I didn’t find this necessary, but assuming the docs are up to date then it is their guidance to add it. You can see the NHibernate documentation here for more on this property.

    My final config section in web.config is as follows:

    <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
      <reflection-optimizer use="false" />
      <session-factory>
        <property name="connection.connection_string">Data Source=your_server;Database=Northwind;UID=username;pwd=password;</property>
        <property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
        <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
        <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
        <property name="show_sql">false</property>
        <property name="connection.release_mode">auto</property>
        <property name="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
        <property name="current_session_context_class">managed_web</property>
    
        <!-- Mapping assemblies -->
        <!-- Can't map it for Fluent NHibernate here; instead, load the mapping assembly in Global.asax.cs.
        If you're still using HBMs, you can use the mapping here or pass the assembly via Global.asax.cs
        as well, just like you can do with the Fluent NHibernate assembly(s). -->
        <!-- mapping assembly="Northwind.Data" -->
      </session-factory>
    </hibernate-configuration>
    
  6. Set the app to use medium trust by adding <trust level="Medium" originUrl="" /> to the system.web section.
  7. Don’t forget to update the NH config with your Northwind database info.
  8. If you want to make use of the WCF part of the Northwind sample app, you’ll need to manually add the APTC attribute to the Northwind.Wcf\Properties\AssemblyInfo.cs file.
  9. Set Northwind.Web as the startup project, rebuild and run.

That’s it, the Northwind sample app should now run successfully in medium trust.

· · ·

Theme Design by devolux.nh2.me