Archive for the ‘C#’ Category

June 24th, 2008

MVC CAPTCHA for Preview Release 3

Since my last release of the MVC toolkit some major changes have taken place in the MVC Framework. I am going to do a quick run through of how they changed the MVC CAPTCHA for the better.

Originally in MVC Preview Release 1 for the MVC CAPTCHA many of you remember that the indicator for a valid CAPTCHA was passed through the parameters of the action method like so:

[ControllerAction]
[CaptchaValidation("captcha")]
public void Register(bool captchaValid, string otherParameters)
{
    // do stuff
}

However when Preview Release 2 came out the ability to pass the parameter through the action method was broken. So I had to create a hack around this:

[CaptchaValidation("captcha")]
public void Register(string otherParameters)
{
    bool captchaValid = (bool)RouteData.Values["captchaValid"];
    // do stuff
}

Apparently without realizing it in Preview Release 1, I had discovered a major feature that everybody that I explained it to saw great potential in. So I submitted a feature request and waited for the ASP.NET Team to get back to me. With the release of Preview Release 3, they finally answered my prayers and added the parameter injection feature back in to the framework.

So now this code works again in the Preview Release 3 version of the MVC CAPTCHA control.

[CaptchaValidation("captcha")]
public void Register(bool captchaValid, string otherParameters)
{
    // do stuff
}

This works because of a new property called ActionParameterson the ActionExecutingContext. It can be used to test and change any of the action methods parameters before the action method has been executed. For the purpose of the MVC CAPTCHA control it allows me to inject a true or false value in to a parameter called captchaValid, so that the action method knows that the CAPTCHA validation passed or failed.

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
	// make sure no values are getting sent in from the outside
	if (filterContext.ActionParameters.ContainsKey("captchaValid"))
		filterContext.ActionParameters["captchaValid"] = null;

	// get the guid from the post back
	string guid = filterContext.HttpContext.Request.Form["captcha-guid"];

	// check for the guid because it is required from the rest of the opperation
	if (String.IsNullOrEmpty(guid))
	{
		filterContext.RouteData.Values.Add(”captchaValid”, false);
		return;
	}

	// get values
	CaptchaImage image = CaptchaImage.GetCachedCaptcha(guid);
	string actualValue = filterContext.HttpContext.Request.Form[Field];
	string expectedValue = image == null ? String.Empty : image.Text;

	// removes the captch from cache so it cannot be used again
	filterContext.HttpContext.Cache.Remove(guid);

	// validate the captch
	filterContext.ActionParameters["captchaValid"] =
		!String.IsNullOrEmpty(actualValue)
		&& !String.IsNullOrEmpty(expectedValue)
		&& String.Equals(actualValue, expectedValue, StringComparison.OrdinalIgnoreCase);
}

Notice in the code above all the filterContext.ActionParameters references, that is the CAPTCHA validation checking for the parameter in the method parameters list and adding the value of the CATPCHA validation to the list. Note that in order for this to work you must already have the captchaValid attribute present in your method, these actions merely fill in the value of the captchaValid placeholder.

For anybody who hasn’t used my MVC CAPTCHA control before, you only need to do two things:

1. You need to register the CAPTCHA image handler.

<httpHandlers>
    <add verb="GET" path="captcha.ashx" validate="false" type="ManagedFusion.Web.Handlers.CaptchaImageHandler, ManagedFusion" />
</httpHandlers>

2. Add the following to the View that you want the CAPTCHA to show in. Note the extension, CaptchaTextBox in HtmlHelper, generates a text box with autocomplete=”off” so that the CAPTCHA box will not have an auto-complete show up.

<label for="captcha">Enter <%= Html.CaptchaImage(50, 180) %> Below</label><br />
<%= Html.CaptchaTextBox("captcha") %>

Which generates the following.

Example of CAPTCHA

If you would like to download the latest copy of the MVC CAPTCHA it is available in my MVC Toolkit.

Download: Coder Journal MVC Toolkit
Source: Coder Journal MVC Toolkit

Tags: , ,

Posted in ASP.NET, C#, How To | kick it on DotNetKicks.com | Bookmark | View blog reactions | 4 Comments »

June 6th, 2008

MVC + Facebook == Wonderful Development Platform

Just recently I started experimenting with the ASP.NET MVC Framework and the Facebook Development Platform, it has been a very bumpy road, but I have ironed out some major issues that I would like to share with you today. I will start with a little history of what I am trying to do. For about a month and a half I have had one of my IdeaPipe interns, Dimitry, experimenting with creating a FBML (Facebook Meta Language) Application with MVC. MVC is an ideal platform for FBML because with MVC you have total control over your markup which is needed to have a lean FBML application. I am not going to go in to the differences of developing an FBML vs IFrame Facebook Application, because that information is easily found with a Google Search. What I am going to talk about is the hurdles I overcame and the custom software I had to develop to get MVC working smoothly with Facebook.

In my last post on the subject I was using the Facebook Developer Toolkit, however because of various implementation problems that were at the foundation of the software when working with MVC, I moved to Facebook.NET which is a object based model for implementing the Facebook Session instead of an inheritance model. What you will need in order to get started is:

One of the problems I ran into was creating a Facebook Session from my Action Method. To remedy this issue I created a FacebookAttribute that is an ActionFilterAttribute and a FacebookWebSession based off of the work done on Facebook.NET.

FacebookAttribute

The FacebookAttribute is added to your Action Methods and will look like the following:

[Facebook(ApplicationName = "IdeaPipe")]
public ActionResult SomeAction(FacebookService facebookService, FacebookSession facebookSession, int myOtherVariables)
{ … }

As you can see the FacebookAttribute just attaches to the Action Method and you just have to specify your ApplicationName that you want to instantiate. The FacebookAttribute also passes in a FacebookService and FacebookSession object for use in your method. The other keys get set in your Web.Config as any standard Facebook.NET application would.

<facebook>
    <application name="IdeaPipe" apiKey="1234" secret="5678" type="GlobalApplication" />
</facebook>

The magic behind this attribute is pretty simple.

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
	FacebookApplicationSettings settings = FacebookSection.GetApplication(ApplicationName);

	ApplicationKey = ApplicationKey ?? settings.ApiKey;
	Secret = Secret ?? settings.Secret;

	FacebookWebSession session = new FacebookWebSession(ApplicationKey, Secret);
	session.Initialize(HttpContext.Current);

	FacebookService service = new FacebookService(session);

	if (filterContext.ActionParameters.ContainsKey(ActionParameterFacebookSession))
		filterContext.ActionParameters[ActionParameterFacebookSession] = session;

	if (filterContext.ActionParameters.ContainsKey(ActionParameterFacebookService))
		filterContext.ActionParameters[ActionParameterFacebookService] = service;
}

Download: FacebookAttribute.cs

FacebookWebSession

The FacebookWebSession was developed out of necessity because the only other FacebookSession objects in Facebook.NET are strongly tied to a WebForms Control that couldn’t be created as easily as I did in the FacebookAttribute. I am going to fore go the source code since much of this is a copy, paste, and rearrange from the Facebook.NET source. Plus much of it is just boring if-then-else statements that go on for awhile and just do a technical setup from the query string fields.

Download: FacebookWebSession.cs

FacebookSection

This is the file that I had to change the one method from internal to public so that I could get the information contained in the Web.Config configuration for my application. Note this file will not be necessary in the future if my changes get accepted in to the Facebook.NET source tree.

This file replaces the \Web\Configuration\FacebookSection.cs of the Facebook.NET source.

Download: FacebookSection.cs
Download: Facebook.NET Binaries For MVC

So that is all that you should need in order to start working with Facebook Applications in MVC. Note that it is still a good idea to include the FacebookApplication control on your pages because it is still needed. The primary goal of the source code above was to allow the use the the FacebookSession in the Action methods. If you have any questions please post them below.

Tags: , ,

Posted in ASP.NET, C#, How To, Programming | kick it on DotNetKicks.com | Bookmark | View blog reactions | 5 Comments »

June 5th, 2008

Give Your ASP.NET Applications Velocity

Scaling ASP.NET Application just got easier with a new technology that Microsoft has just released that they have dubbed codename “Velocity”. This product is still in the early stages of development, but it is meant as a direct competitor against memcached. If you are not familiar with memcached, here is how it is described in Wikipedia:

memcached (pronunciation: mem-cache-dee) is a general-purpose distributed memory caching system that was originally developed by Danga Interactive for LiveJournal, but is now used by many other sites. It is often used to speed up dynamic database-driven websites by caching data and objects in memory to reduce the number of times the database must be read. Memcached is distributed under a permissive free software license.

So basically it allows you to create a distributed memory cache across your server farm, that allows any computer in the server farm to access the data in the cache. So there is no more issues with storing session data on server farms, or worrying about setting up common SQL stores of temporary data. This is also very practical for reducing database stress on Web 2.0 sites, many of the top Web 2.0 sites use this to reduce reads on the database.   The biggest user of memcached to date is Facebook.  This diagram below gives a basic idea of how distributed caching works.

Diagram of Velocity

There have been many Open Source projects for getting memcached working on C#, and most have been pretty successful, but because memcached was designed for the UNIX environment, porting memcached to a Windows Service has always lagged behind the actual releases of the required libraries to get memcached working. Enter Velocity, as the Velocity team describes:

Velocity is intended to provide distributed caching (in memory) for all .NET applications – from enterprise scale to web-scale. We believe that there are many applications that need a distributed caching mechanism, and that there is, therefore, a need for distributed caching as a core part of the .NET platform. We expect to have more integrated support for this functionality with other parts of the .NET platform in our upcoming releases.

There is also a pretty nice Velocity writeup on MSDN that goes in depth about how Velocity works as well as providing some basic code examples on how to get data into and out of your Velocity Cache. The current set of features looks pretty nice, and I can’t wait for Velocity to become more stable so I can introduce it in to the IdeaPipe mix.

Here is a breif overview of the Current Features:

  1. Support for different cache types, partitioned and local
  2. Support for different client types, simple and routing
  3. Load Balancing & Dynamic Scaling
  4. ASP.Net Integration, currently there is only a Session Provider
  5. Key and Tag based Access

And Beyond

  1. Availability - support for Failover when machines go down
  2. Replicated Cache - another cache type
  3. Embedded Topology - run the cache embedded within you application instead of as a cache service
  4. Notifications - Get notified when a object in the cache is updated
  5. Consistency Models - Support for both weak and strong consistency when doing reads/writes
  6. Native client access to the cache service (E.g - PHP, C++ etc)
  7. Manageability & Administration

Tags: , , , , , ,

Posted in ASP.NET, C#, Review | kick it on DotNetKicks.com | Bookmark | View blog reactions | 5 Comments »

May 27th, 2008

ASP.NET MVC Preview 3 Released

The ASP.NET MVC Team has released an refresh of MVC. To all those that are interested the new Preview Release is posted at:

http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=13792

The new release contains many new features over the 2nd Preview Release and the Interim Release from a month a half ago. In this post I am going to outline the features that are new from the Interim Release to Preview Release 3.

Action Method and Result Changes

As you remember from the previous release, you are now required to return an ActionResult. Many of the ActionResults were renamed to the following types:

  • ViewResult: Renders the specified view to the response.
  • EmptyResult: Does nothing. Returned if the action method must return a null result.
  • RedirectResult: Performs an HTTP redirect to the specified URL.
  • RedirectToRouteResult: Given some routing values, uses the routing API to determine the URL and then redirects to that URL.
  • JsonResult: Serializes the specified ViewData object to JSON format.
  • ContentResult: Writes the specified text content to the response.

There were also new helper methods added to the Controller class for these new ActionResult types.

  • View: Returns a ViewResult instance.
  • Redirect: Redirects to the specified URL. Returns a RedirectResult instance.
  • RedirectToAction: Accepts an action (and optionally a controller) and redirects to another controller action. Returns a RedirectToRouteResult instance.
  • RedirectToRoute: Redirects to a URL that is determined by the routing API. For example, this method lets you specify a named route. Returns a RedirectToRouteResult instance.
  • Json: Returns a JsonResult instance.
  • Content: Sends text content to the response. Returns a ContentResult instance.

One of the more interesting ActionResults is the JsonResult which returns a serialized form of your ViewData object using the JavaScriptSerializer class. I don’t know why they didn’t use the DataContractJsonSerializer, but the team probably had their reasons.

View Data Changes

There is also the addition of implicit conversion for Action methods that return anything other than an ActionResult.

If an action method returns null (or has a return type of void), the action invoker implicitly provides an EmptyResult instance, which does nothing. If an action method returns anything other than an ActionResult instance, the action invoker calls ToString(CultureInfo.InvariantCulture) on the instance and then wraps the return value with a ContentResult object, which writes the content to the response.

A Model property was added to ViewDataDictionary. For ViewDataDictionary, the type of this property is System.Object. For ViewDataDictionary<T>, the type of this property is T.

The ViewData property of ViewPage<T> is no longer replaced by T. In Preview 2, the MVC framework replaced the ViewData property with the specified strongly typed view data (that is, the T in ViewPage<T>). In Preview 3, the Model property of ViewData is set to the instance of type T.

Route Changes

An IRouteConstraint interface was added.

If a constraint value is specified as a string, the string is interpreted as a regular expression. If the constraint value is specified as an instance of IRouteConstraint, route processing calls the Match method of IRouteConstraint.

A new HttpMethodConstraint type was added, which changes the way you constrain routes on the HTTP method. Unlike previous versions of ASP.NET routing, in this release, the constraint name “httpMethod” is no longer special. Instead, use the HttpMethodConstraint to add a constraint based on HTTP verbs. The following example shows how to use the HttpMethodConstraint type.

routes.MapRoute(
    "route-name",
    "{controller}/update",
    new {action = "update"},
    new {httpMethod = new HttpMethodConstraint("PUT", "POST")}
);

Other Changes

The versions of the System.Web.Abstractions and System.Web.Routing assemblies that are included with the MVC project template have been changed to version 0.0.0.0. The versions that are included in the Preview 3 release are newer than those that ship in the .NET Framework version 3.5 Service Pack 1 Beta. Therefore, they were assigned a private version number so that no conflict occurs between the assemblies in this release and the assemblies installed by the .NET Framework 3.5 SP1 Beta release.

And a ton of bug fixes

So in conclusion the ASP.NET MVC team has released another great release. Many of the new features have been on the request list of many of the active MVC developers. I still have to try out a couple of my requests to see if they are included, but I will make sure to provide a new post with those details.

Update: ScottGu has just released his notes on the MVC Preview Release 3, which I must admit are more in depth than my own.

Update 2: I have also updated IdeaPipe to reflect the latest PR3 changes. It took me about an hour to go through all my code and then test it. I am pleased to report the default page is now working, so that you don’t need the Default.aspx page anymore.

Tags: ,

Posted in ASP.NET, C#, Programming, Review | kick it on DotNetKicks.com | Bookmark | View blog reactions | 1 Comment »

May 23rd, 2008

Microsoft Source Analysis Still Needs Work

Somebody is wrong on the internetMicrosoft just released a tool called Microsoft Source Analysis for C#. Apparently it is a tool they use internally to make sure all their souce code looks the same and is easily readable by all those who use it. According to the blog post that announced this:

Source Analysis comes with a set of default rules analyzers covering approximately 200 best practice rules. These rules are full compatible with the default layout settings in Visual Studio 2005 and Visual Studio 2008.

Specifically, these rules cover the following, in no particular order:

  • Layout of elements, statements, expressions, and query clauses
  • Placement of curly brackets, parenthesis, square brackets, etc
  • Spacing around keywords and operator symbols
  • Line spacing
  • Placement of method parameters within method declarations or method calls
  • Standard ordering of elements within a class
  • Formatting of documentation within element headers and file headers
  • Naming of elements, fields and variables
  • Use of the built-in types
  • Use of access modifiers
  • Allowed contents of files
  • Debugging text

So being a neat freak about my code I had to download this tool and give it a shot. I was very excited about the tool and had great hopes for it. However when I actually tried the tool, there was no configuration for turnning off some of the rules that you didn’t agree with, like there is in the code analysis analyics tool.

I got literlly over 1000 messages about using spaces instead of tabs, in 3 files, because they felt it nessisary to alert me about every single line of code in my files. They also suggest I put the using statements inside of my namespace. I don’t know about you, but I hate the look of that, because stuff should be logically packed together. Only the classes show up in the namespace when you are referencing them, and the using statements are just a compiler indicator, not actual code. It did alert me about a couple of things that I found useful, such as when some of my XML comments weren’t long enough and or missing, and other nicities that I can agree with.

However, I am one of those strange developers, according to Microsoft, that likes to use tabs and have my declartion of using statements outside of my namespace. If I were to take this tool seriously I would have to be shunned from the Microsoft Campus and shammed in to never coding again. I guess I should start including the Rob Conery SupressMessage on my code:

[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "1000:YouShouldntBeCoding", MessageId = "1#",
Justification="That's not very nice... but I'm used to it :p")]

Of course I am joking about this, and I think these rules from Microsoft are totally wrong and out of wack with most C# developers. Mostly for the fact that the rules are not fully compatible with Microsofts own defaults they ship. First of all when you create a new class in C# the using statements are outside of the class you create. Second I find that using spaces just forces me to resync my code formatting more often because the spaces tend to get out of wack when you are developing software. Plus you are creating 400% more bytes in your file by using spaces over tabs. I know harddisk space doesn’t cost that much, but if you are using a system like TFS it just adds unnessisary bloat to your SQL Server database.

I would have probably agreed with a good 95% of their over 200 rules, if I could get past the 3 files with over 1000 messages about using spaces instead of tabs. I really feel one alert is good enough. It still has many usability and configuration issues to overcome before it will be widely accepted by non-Microsoft developers. Plus all that being said above, I am just stubborn and like my coding style.

Posted in C#, Rant | kick it on DotNetKicks.com | Bookmark | View blog reactions | 8 Comments »

April 24th, 2008

Interesting Extension Hack To Get Around NullReferenceException’s

Today I came across an interesting extension pattern that I didn’t know how the runtime would react. Normally when you do something like the following:

string s = null;
Console.WriteLine(s.Trim()); // throws NullReferenceException

You get a NullReferenceException meaning that you didn’t first check to see if the object was null before trying to call one of its methods. This is pretty common and results in patterns that usually look like this:

string s = null;
string result = null;

if (s != null)
    result = s.Trim();

Console.WriteLine(result);

This results in a ton of extra code to just verify you inputs. It’s a dirty task but somebody has to do it. So today it occurred to me that maybe extension methods were my answer to this code bloat. To better understand extension method, Scott Hanselman has done a great job explaining how they function and what they look like to the CLR.

So I whipped up the following console application and tested my theory out.

public static class Extension
{
    public static string TryTrim(this string s)
    {
        if (s == null)
            return s;

        return s.Trim();
    }
}

class Program
{
    static void Main(string[] args)
    {
        string s = null;
        Console.WriteLine(s.TryTrim());  // notice that I don’t have the code bloat like above
    }
}

This works without a NullReferenceException because the code actually looks like this to the compiler.

public static class Extension
{
    public static string TryTrim(string s)
    {
        if (s == null)
            return s;

        return s.Trim();
    }
}

class Program
{
    static void Main(string[] args)
    {
        string s = null;
        Console.WriteLine(TryTrim(s));  // this is how the run time sees the code
    }
}

So with this new understanding of extension methods you don’t have to worry about checking if a variable is null or not before trying to use an extension method. The more I use extension methods the more I love them.

Tags: , ,

Posted in C#, Programming | kick it on DotNetKicks.com | Bookmark | View blog reactions | 9 Comments »

April 13th, 2008

Coder Journal’s MVC Toolkit

Today I decided to release a toolkit that I have been building over the past couple of months. Most of the code in the toolkit is related to MVC. Here is a list of the features:

ActionFilterAttribute’s

  • HttpPostOnlyAttribute
    Only allows POST to be made against the action.
  • CacheAttribute
    Sets the action’s response as cacheable.
  • CompressAttribute
    Compresses the action’s response using GZip or Deflate encoding.
  • ServiceAttribute
    Marks an action as able to provide the ViewData as JSON, XML, or JSONP.
  • ServiceOnlyAttribute
    Marks an action as only able to provide the ViewData as JSON, XML, or JSONP, that means no HTML.
  • ExceptionHandlerAttribute
    Handles any exceptions thrown from an action, and redirects it to another page, or another action.
  • CaptchaAttribute
    I did a whole post on providing a CAPTCHA for your MVC action.
  • AllowedHttpMethodsAttribute
    Only the HTTP methods entered in to this filter are allowed for your action. Available HTTP methods are OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, and CONNECT.

ViewEngines’s

  • ServiceViewEngine
    This view engine provides the serialization of the ViewData to JSON, XML, or JSONP. It is set when one of the following is requested from the ServiceAttribute above.

Route’s

Method Extensions

  • Redirect extends HttpResponse
    I have had a long standing discontent with the Redirect method of the ASP.NET. I have talked about good use of HTTP Status Codes before. There are at least 3 status codes that you want to consider before choosing a response status code of 302. Just to reiterate my post on the subject use 303 to redirect from a form POST, use 307 when you want to redirect to a page that is going to change with each request, use 301 if you want to permanently redirect one URL to another.I created the, Redirect, extension method on HttpResponse so that the status code could be set for the redirect.

View Source: Coder Journal MVC Toolkit Source
Download Binary: Coder Journal MVC Toolkit Binary

Read the rest of this entry »

Tags: , ,

Posted in ASP.NET, C#, Personal | kick it on DotNetKicks.com | Bookmark | View blog reactions | 9 Comments »

April 3rd, 2008

Why is JSON Deserialization so Important to Developers?

Recently I have been working on a RESTful interface for a Web 2.0 project that I will be releasing very soon. And one of the self imposed requirements that I set out to achieve was to have the RESTful interface output the same structure JSON as XML. This way that any developer using the interface would feel comfortable using the JSON and XML interchangeably. But, I have been having a lot of trouble recently getting my JSON and XML to output the same structure when using the built in .NET methods. I have tried the following:

  • JavaScriptSerializer/XmlSerializer
  • DataContractJsonSerializer/DataContractSerializer

Neither can be forced to output the same structure. Mostly because they are both concerned about serialization and deserialization. Now I ask the question, Why is JSON deserialization so important to have? JSON stands for JavaScript Object Notation, the keyword in there is JavaScript, why are we trying to force a technology designed for a specific language and purpose in to a different technology. In my opinion it seems akin to trying to communicate between two JavaScript methods with the following C# code:

struct MyData {
    public string Name = "Nick Berardi";
    public Uri Blog = new Uri("http://www.coderjournal.com");
    public DateTime BirthDate = new BirthDate(1980, 3, 14, 0, 0, 0);
}

There is no point to doing that because the JavaScript language already has a way to communicate objects, it’s called JSON. So why as C# developers, or whatever language we use, we insist on creating a deserializer when only a serializer is needed to translate our preferred object to JSON so that JavaScript, different language, can understand. By creating a deserializer we are basically encouraging/saying that this is a valid way to communicate between languages.

I personally see JSON as a communication protocol between two non-JavaScript languages as a fad. The communication between two non-JavaScript languages has already been decided to be either Remoting or XML, both were created with this idea of object transportation in mine, and both are very extensible and don’t fall short where JSON does.

Now that all that is said, I personally don’t have a problem with JSON having a deserializer, because there is going to be a time when you need to deserialize JSON, but it should be the exception not the rule, and it shouldn’t be part of the JSON serializer. I say this for the following reason, because when you combine a serializer and deserializer there is an expectation that the type is going to be the same going in as coming out. This was planned for in XML, with XML namespaces to define the type, however this was not planned for in JSON, so special cases have to be developed in order to support deserialization such as the inclusion of “__type” property in the JSON object. As illustrated in this article from Scott Hanselman:

{ "__type":"ConsoleApplication1.Person, ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" ... }

You may say, “So what, that is what needs to be done to deserialize the object.” Well that my friends is called a Hack, and as professional developers we shouldn’t be hacking technologies, that were not designed for our purpose, together with our applications.

Tags: , ,

Posted in C#, Programming, Rant | kick it on DotNetKicks.com | Bookmark | View blog reactions | 1 Comment »

March 31st, 2008

Force MVC Route URL to Lowercase

So one of my pet peeves in web development is mixed case URL’s. And I usually make sure that all my URL’s in my personal projects follow this standard. I also believe, contrary to my URL case standard, that my code should follow standards .NET naming techniques, such as Pascal casing for my method names.

These two naming standards come in to conflict with MVC because the name of the action method in the controller is used in its native Pascal case. Which generates URL’s that look like this:

/Home/Index
/Home/About

However I want them to be generated like this:

/home/index
/home/about

So I developed my own Route based off of the System.Web.Routing.Route to force everything to lowercase.

public class LowercaseRoute : System.Web.Routing.Route
{
	public LowercaseRoute(string url, IRouteHandler routeHandler)
		: base(url, routeHandler) { }
	public LowercaseRoute(string url, RouteValueDictionary defaults, IRouteHandler routeHandler)
		: base(url, defaults, routeHandler) { }
	public LowercaseRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, IRouteHandler routeHandler)
		: base(url, defaults, constraints, routeHandler) { }
	public LowercaseRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, RouteValueDictionary dataTokens, IRouteHandler routeHandler)
		: base(url, defaults, constraints, dataTokens, routeHandler) { }

	public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
	{
		VirtualPathData path = base.GetVirtualPath(requestContext, values);

		if (path != null)
			path.VirtualPath = path.VirtualPath.ToLowerInvariant();

		return path;
	}
}

For anybody as anal as me about stupid stuff such as casing of URL’s you should find this class up above a welcomed addition to your MVC projects.

Tags: , ,

Posted in ASP.NET, C# | kick it on DotNetKicks.com | Bookmark | View blog reactions | 6 Comments »

March 13th, 2008

ASP.NET MVC: Securing Your Controller Actions (The .NET Framework Way)

So I just read Rob Conery’s blog post on Securing Your Controller Actions in MVC. I was a little perplexed about why guys at Microsoft love to reinvent stuff they have already done. I know Rob Conery is a really smart guy and has a wonderful grasp of the .NET framework, so I would have to assume he knows about what I have outlined below. My only guess is that he just wanted to re-invent something that is already built in to the framework using his own code.

Basically what Rob did was the following, created two attributes for attaching on the MVC Controller Action:

RequiresAuthenticationAttribute

[RequiresAuthentication]public void Index () {
    RenderView(”Index”);
}

RequiresRoleAttribute

[RequiresRole(RoleToCheckFor = "Member")]public void Index () {
    RenderView(”Index”);
}

I have accomplished the same thing using an attribute that has been apart of .NET since 1.0. The attribute is called PrincipalPermissionAttribute and is part of the System.Security.Permission namespace. The best thing about it is that it is integrated in to the run time, so there is no chance of unwanted people getting through. It also accomplishes both of Robs attributes up above, plus more. Using the examples up above I will demonstrate how to use PrincipalPermissionAttribute to secure and protect your Controller Actions.

RequiresAuthenticationAttribute

[PrincipalPermission(SecurityAction.Demand, Authenticated = true)]public void Index () {
    RenderView(”Index”);
}

RequiresRoleAttribute

[PrincipalPermission(SecurityAction.Demand, Role = "Member")]public void Index () {
    RenderView(”Index”);
}

In addition if you were inclined you can restrict things to just one user name with PrincipalPermissionAttribute. So for instance if you wanted to restrict adding and removing roles and their permissions to only the username “SiteAdmin”, you would do the following.

[PrincipalPermission(SecurityAction.Demand, Name = "SiteAdmin")]public void RolesAdmin () {
    RenderView(”RolesAdmin”);
}

As you can see this is very powerful. Built in to the run time, by extending the CodeAccessSecurityAttribute, so it operates at a lower level than Rob’s solution. Only requires the use of one attribute, and throws only one exception called SecurityException.

I really hope that ASP.NET MVC doesn’t turn in to a lets-redo-everything-that-already-works framework, because they still have many issues that they need to achieve before ASP.NET MVC is usable, and focusing on things that are already implemented in the .NET framework doesn’t seem like the right course of action when developing a new offering.

Read the rest of this entry »

Tags: , , , , , ,

Posted in ASP.NET, C#, How To, Programming, Rant | kick it on DotNetKicks.com | Bookmark | View blog reactions | 8 Comments »