Tag Archives: MVC

PetaPoco Performance Statistics

The other day Sam from stackoverflow blogged about a slow page caused by a combination of problems resulting in them using Dapper to map native SQL to the objects resulting in a nice performance improvement.

I liked how he made the queries executed for the current request display in html comments in the html source, so I thought I would see if I could implement the same thing with PetaPoco. I intend to go through how I implemented the following in future posts (after I go through some basics), but for the moment I’ll give you a quick screen grab of what it looks like. Thanks goes to Sam for providing the inspiration.

petapoco_db_stats

Integrating xVal Validation with Linq-to-Sql

In a previous post I showed you how you can use xVal and the IDataErrorInfo class to add validation to your Asp.net MVC website. In this post I will extend that to Linq-to-Sql and the classes it generates.

The northwind database has a suppliers table. The info contained below is using that table with linq-to-sql.

After adding the table to the designer, a Supplier class gets constructed in the background. This class is a partial class which means we can add to it without changing the code auto-generated in the designer.cs file.

We can then create a partial class called Supplier inheriting from Custom Validation and add a MetadataType attribute to it. This attribute specifies the class for which use for validating the Supplier class.


[
MetadataType(typeof(SupplierValidation))] public partial class Supplier : CustomValidation { }

We can then create the SupplierValidation class specifying the properties of the Supplier class we would like to be validated. For instance here I only want to validate the ContactName and the ContactTitle of the Supplier.

    
public class SupplierValidation { [Required] public string ContactName { get; set; } [Required, Range(0, 10)] public string ContactTitle { get; set; } }

This specifies that both fields are required and that the ContactTitle cannot be more than 10 characters in length.

The other benefit of using the buddy class here is that if you need to regenerate a table in the linq-to-sql designer, you won’t lose your changes because they’re contained in a separate file.

From here when a Supplier gets passed to in as a parameter on a Controller action it will be validated using the rules in the Supplier Validation class.

Cheers,

Adam

Running ASP.NET MVC Applications Under IIS6

Yes…Finally…I have full control of my HTML again, but am still able to work with a great language like C#. MVC is here and its great. I’m absolutely loving it. But how the heck do you get it to work under IIS6. What if I want extensionless URL’s? Here is a few options for you.

Option 1:
Running IIS with Wildcard Application mapping.

This option allows extensionless URL’s but a what performance price. Every single request including images, files and css etc. will get passed through the aspnet_isapi.dll. For small sites this may not be a huge issue, but small sites soon because large sites and this then becomes an issue.

I’m not going to run through how to do this, because there are already some nice blogs about this and I don’t really recommend this option.

Option 2:
Running IIS with .mvc (or whatever you like) extensions.

I started out running my site (schotime.net) like this, however in the end I decided on Option 3.
URLs look like this.   /Home.mvc/Index   rather than /Home/Index  which is not that bad but again not as nice as the latter.

Anyways here’s how you set this up.
Firstly your global.asax.cs should look like this.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace MVCApplication1
{
    public class MvcApplication : System.Web.HttpApplication
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                "Default",                                              
                "{controller}.mvc/{action}/{id}",                       
                new { controller = "Home", action = "Index", id = "" }  
            );

            routes.MapRoute(
                "Defaultest",                                           
                "Default.aspx",                                         
                new { controller = "Home", action = "Index", id = "" }  
            );

        }

        protected void Application_Start()
        {
            RegisterRoutes(RouteTable.Routes);
            RouteTable.Routes.RouteExistingFiles = true;
        }
    }
}

This will get you started. All you need to do then is map the extension .mvc to the aspnet_isapi.dll in IIS under Home Directory -> Configuration -> Mappings or use an already mapped extension like .aspx and your mvc application should work.

Option 3:

This option requires the use of a clever isapi filter to rewrite the URLs.

I originally read an article on Bia Securities which uses the Isapi_rewrite 3rd party plugin however, Isapi_rewrite is not free so I thought I would find a suitable open source solution. Here it is: Ionic Rewriter -> http://www.codeplex.com/IIRF

It works in much the same way as the isapi_rewrite but will a few little differences. Once you download the IsapiRewrite4.dll, place the dll in a directory eg. C:\WINDOWS\system32\inetsrv\IIRF and run through the installation instructions included in the download (readme.txt) under Installation. Next comes the configuration. Firstly here is the IsapiRewrite4.ini configuration file ported from the Bia Securities article.

#RewriteLog  c:\temp\iirfLog.out

#RewriteLogLevel 3

RewriteRule ^/Default\.aspx /Home.mvc [I,L]

RewriteRule ^/$ /Home.mvc [I,L]

RewriteRule ^/([\w]+)$ /$1.mvc [I,L]

RewriteRule ^/(?!Content)([\w]*)/(.*) /$1.mvc/$2 [I,L]

The [I,L] stands for a case-insensitive match and to stop processing if the current rule is a match.

Important Note:

Any physical files that you directly linked to should not be routed. In my MVC folder system I store all of these files under the /Content directory. Wherever you store your files replace the text Content with the folder that your files reside. otherwise images, css etc. will fail to display.

Now all that’s left to do is to modify the global.asax.cs to support this.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace MVCApplication1
{
    public class MvcApplication : System.Web.HttpApplication
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                "Default",                                              // Route name
                "{controller}/{action}/{id}",                           // URL with parameters
                new { controller = "Home", action = "Index", id = "" }, // Parameter defaults
                new { controller = @"[^\.]*" }
            );

            routes.MapRoute(
                "Defaultmvc",                                               // Route name
                "{controller}.mvc/{action}/{id}",                           // URL with parameters
                new { controller = "Home", action = "Index", id = "" },     // Parameter defaults
                new { controller = @"[^\.]*" }
            );
        }

        protected void Application_Start()
        {
            RegisterRoutes(RouteTable.Routes);
        }
    }
}

Note:  The line with this on it -> new { controller = @"[^\.]*" }   is very important. The routes won’t work without it.

And that’s it! You’re done.

Personally I like the last option but if you have no access to your hosting web server then Option 2 is probably the best.

Schotime