Lorenz Cuno Klopfenstein

Posts tagged "ASP.NET"

This is an update over an old post about running Lucene.Net on a medium trust web hosting service with NHibernate.Search.

Lucene logo

After more than one year, the full-text search library has changed a bit: most notably, Lucene.Net has exited the "incubation" stage and is now an officially featured project of the Apache foundation. That's great news. Unfortunately, the project's homepage hasn't been updated and that caused a bit of confusion on my part. The updated SVN repositories are now here:

https://svn.apache.org/repos/asf/lucene/lucene.net/

and the stable binary packages are way outdated. I suggest you build your Lucene.Net dll from source code.

The NHibernate.Search source code has changed as well and includes several improvements. For instance, the issue I was reporting in my original post has disappeared (I'm not sure if this depends on a fix in the library or in my code, but the deadlock is gone) and the Optimize() method actually performs the optimization of Lucene's index files.

More...

Posted on Wednesday, January 20, 2010
173 Views
1 comments posted

I recently updated the source code to my Babil project in order to port it to the new ASP.NET MVC 2 beta. I decided I could as well update all other libraries the project depends on, which have been updated too in the meantime.

This took some time, but if you want to create a new website project based on ASP.NET MVC and NHibernate, here's the latest bits:

  • Get the ASP.NET MVC 2 beta source code from Codeplex and compile it. Remember to also compile the Microsoft.Web.Mvc.dll library that contains some useful code.
  • Get NHibernate 2.1, the latest release of the popular O/RM library.
  • Get the latest MySQL .NET connector (6.1.3) if you use NHibernate against a MySQL database.
  • If you use NHibernate.Search for full text indexing:
  • If you use NHibernate.Validator, get the source code and compile that too against the latest NHibernate DLL.
  • For your dependency injection needs, you might use Autofac. In that case, you also need to download the latest stable Autofac library and the source code of the web integration library. This integration library must be compiled using the beta version of ASP.NET MVC 2.

That's it, now throw everything in the /Bin folder and - crossing fingers - you should be able to finally write some own code.  :)

Posted on Wednesday, December 16, 2009
202 Views
0 comments posted
ASP.NET MVC logo

As I mentioned in my previous article about how to render an ASP.NET MVC View to a string, there are several methods to do it and they probably are quite different performance-wise. Well, this time I've got some benchmarks.  :)

More...

Posted on Sunday, November 01, 2009
547 Views
0 comments posted

Output caching in ASP.NET MVC is usually done via the built-in OutputCacheAttribute, an attribute that marks an action as cacheable and relies on the default ASP.NET caching module. This means that the caching is usually very efficient and doesn't go through the MVC framework at all in case of a cache-hit.

Oooh, donut! by mhaithaca on Flickr

Donut caching, i.e. returning a cached page with a part that is not cached and rendered at each request, can be done in some ways. Usually they use features of the WebForms engine in ASP.NET, for instance using the Substitution control or explicitly caching UserControls. A nicer method is the one suggested by Maarten Balliauw, which requires manual caching and embedding the "donut holes" as strings in the cached page.

Starting from this idea, I wrote a donut caching method for my blogging engine BABiL that should be able to work with every view engine, integrates with MVC ActionResults (no change required on the views) and partial requests.

More...

Posted on Thursday, October 22, 2009
Tagged as
715 Views
4 comments posted
ASP.NET MVC logo

A common need I have in my ASP.NET MVC based projects (and other people have too, as it appears) is to render a complete "View" to string instead of the http response and then present it or embed it in another rendered view.

Finding a solution isn't very easy because view rendering (using the default WebForms view engine) is tightly coupled with the response stream and therefore you have to intercept the output in some rather complex way. There are several different solutions online, for instance using filters on the HttpResponse or taking the view as a WebForms control and rendering it directly.

More...

Posted on Wednesday, October 14, 2009
Tagged as
2758 Views
25 comments posted

ASP.NET MVC logo Today I wanted to add server-side caching to Babil. I had already read different opinions and techniques to do it and one in particular was interesting: it was something like "of what use is caching if the only thing the server ever does is concatenating some strings and fetch data right out of the ASP.NET cache" (as is the case using NHibernate's second level cache). Since I have no idea, the only way to find out, as usual, is to measure.  :)

Turns out that generating a complex page takes almost as long as 200ms, while returning the same page stored inside the cache takes at most 10ms (these are the values I get on the ASP.NET server included with Visual Web Developer, I expect Babil to perform much better running on a real server and not with a debug build of course). Anyway, the difference is quite noticeable and convinced me to try and get output caching done.

More...

Posted on Thursday, January 15, 2009
Tagged as
1527 Views
15 comments posted

Disclaimer: this is a roundup of things I got from the NHibernate documentation, the ufficial forum or some random blog post, they seem to work for me but I'm not completely sure this is the "correct" way of doing things.

NHibernate logo The custom CMS I'm currently working on (and that is managing this website) relies on NHibernate as its O/RM, which currently provides two separate caching mechanisms.

The first one is the first level cache. It's a local cache to each separate NHibernate Session (a single ADO connection to the database, that usually is opened when the server receives an HTTP request and is closed again when the request is completed). NHibernate will keep all objects associated to that particular session in its cache. This cache is lost as soon as the session is disposed.

NHibernate also allows you to select one of the many cache providers you can find on NHForge.org as a second level cache. This type of cache is persistent, lives across multiple request and is used by all sessions concurrently. Roughly speaking, when an object instance is fetched from the database all values of the object are stored in the cache. When the same object is requested again, NHibernate will dehydrate the object using the values found in the cache which are associated to that particular identifier of the object.

This means that no instances are stored in the cache, but only values. As explained in the documentation, this means that if you manipulate objects loaded through NHibernate you won't risk disrupting the cache, while relationships and associations between instances will always be consistent.

More...

Posted on Monday, January 05, 2009
6954 Views
15 comments posted

I'm continuing to add more functionalities to the website and this time I've been working on "e-mail notifications" (which are sent to whoever commented on a post when a new comment is written). In order to send those e-mails asynchronously I decided to add the Quartz.NET Job Scheduler to the project and try to get it working.

So, after struggling to setup NHibernate, use the new ASP.NET MVC framework and getting Lucene.NET and NHibernate.Search to work, let's tackle the next library...  :S

Quartz.NET logo The latest version (1.0) of the library should be compatible with "partial trust" scenarios, but nonetheless still failed to work on the live website. I digged around in the source code to find the pieces of code which didn't work: I've documented my findings on the Quartz.NET mailing list and it should be fixed in the next versions (actually, the Common Logging framework would need to be fixed too for partial trust scenarios).

Anyway, if you need Quartz.NET now, here's what you need to do.

Remove the Common Logging library

After grabbing the source code from SourceForge, the first thing to do is to remove all references to the Common Logging library (which, as said, doesn't run on medium trust right now). To do so, remove the dll reference from the Quartz project:

Remove the Common Logging dll reference from the project.

Ok, now we end up with a lot of errors in the code.  :D Instead of removing the references to the logging library from the code, we can simply re-route all calls to a fake stub of the library, implementing some of the classes and copying the interface signatures with Reflector.

First of all, ILog.cs:

namespace Quartz {
	public interface ILog {
		// Methods
		void Debug(object message);
		void Debug(object message, Exception exception);
		void Error(object message);
		void Error(object message, Exception exception);
		void Fatal(object message);
		void Fatal(object message, Exception exception);
		void Info(object message);
		void Info(object message, Exception exception);
		void Trace(object message);
		void Trace(object message, Exception exception);
		void Warn(object message);
		void Warn(object message, Exception exception);

		// Properties
		bool IsDebugEnabled { get; }
		bool IsErrorEnabled { get; }
		bool IsFatalEnabled { get; }
		bool IsInfoEnabled { get; }
		bool IsTraceEnabled { get; }
		bool IsWarnEnabled { get; }
	}
}

Then ILoggerFactoryAdapter.cs:

namespace Quartz {
	public interface ILoggerFactoryAdapter {
		// Methods
		ILog GetLogger(string name);
		ILog GetLogger(Type type);
	}
}

Then create an implementation of ILog (I called it LogImpl) which simply does nothing on each call and returns false on all properties. Finally, let's implement LogManager.cs:

namespace Quartz {
	public sealed class LogManager {
		public static ILog GetLogger(string name) {
			return new LogImpl();
		}
		public static ILog GetLogger(Type type) {
			return new LogImpl();
		}

		// Properties
		public static ILoggerFactoryAdapter Adapter { get; set; }
	}
}

We don't need to implement the full class, just the methods used by Quartz, and return an instance of our stub logger.

Fixing Quartz.NET

Ok, now that the Common Logging library has been removed cleanly, we need to fix some of the calls in Quartz.NET which are not allowed in partial trust. Let's start with /Impl/StdSchedulerFactory.cs: in the Initialize() method you'll find a call to GetEnvironmentVariable() that must be removed.

string requestedFile = null;// Environment.GetEnvironmentVariable(PropertiesFile);

And then the same function call must be removed from the OverrideWithSysProps() method:

private static NameValueCollection OverrideWithSysProps(NameValueCollection props)
{
    NameValueCollection retValue = new NameValueCollection(props);
    /*ICollection keys = Environment.GetEnvironmentVariables().Keys;

    foreach (string key in keys)
    {
        retValue.Set(key, props[key]);
    }*/
    return retValue;
}

Ok, now to the /Core/QuartzScheduler.cs file. This class calls the GetAssembly() method to get the library's version number when initialized: this isn't allowed either on medium trust, so we'll have to remove that code.

/// 
/// Initializes the <see cref="QuartzScheduler"/> class.
/// 
static QuartzScheduler()
{
	//Assembly asm = Assembly.GetAssembly(typeof(QuartzScheduler));
	//versionInfo = FileVersionInfo.GetVersionInfo(asm.Location);
	//versionInfo = new FileVersionInfo();
}

And finally, remove all code in the "Version" properties with some hard-coded arbitrary values (you won't need them in most cases I think), like so:

public string Version
{
    get {
		//return versionInfo.FileVersion;
		return "1.0.0";
	}
}

That's it! Recompile the whole thing and add the new library to your project.  :)

Lazy?

If you don't want to mess with the source code and simply want a working version of Quartz.NET 1.0, download it here.

Posted on Wednesday, November 19, 2008
Tagged as
1898 Views
8 comments posted

An updated post about Lucene.Net and NHibernate.Search on medium trust has been published. (more...)

Posted on Sunday, October 26, 2008
3277 Views
12 comments posted

Following my previous article about how I deployed this new ASP.NET MVC website on IIS 6 and .NET 2.0, now I'll explain how I made NHibernate (an Object-Relational mapper for .NET) work on the same platform (while in the next article I'll tackle Lucene.NET and NHibernate.Search). (more...)

Posted on Saturday, October 25, 2008
1712 Views
18 comments posted
Back to Klopfenstein.net
Clemens Klopfenstein Serena Kiefer Lukas Tiberio Klopfenstein Lorenz Cuno Klopfenstein
English German