Posts Tagged ‘ASP.NET’

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 »

April 16th, 2008

ASP.NET MVC Interim Released

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

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

The new release seems to rely on a non-CodePlex open source project.  Is this the first sign of Microsoft’s commitment to open source?

The Release Notes have a lot of good information about new features and bug fixed included in this release:

This CodePlex refresh of the ASP.NET MVC source code includes a number of key changes and refactorings.
To see a full list of API changes, take a look at the attached zip file produced using
Framework Design Studio.

MVC Changes Since Preview 2

  • Action methods on Controllers now by default return an ActionResult instance, instead of void.
    • This ActionResult object indicates the result from an action (a view to render, a URL to redirect to, another action/route to execute, etc).
    • Each “result” is a type that inherits from ActionResult. To render a view, return a RenderViewResult instance.
  • The RenderView(), RedirectToAction(), and Redirect() helper methods on the Controller base class now return typed ActionResult objects (which you can further manipulate or return back from action methods).
  • The RenderView() helper method can now be called without having to explicitly pass in the name of the view template you want to render.
    • When you omit the template name the RenderView() method will by default use the name of the action method to determine the view template to render.
    • So calling RenderView() with no parameters inside the About() action method is now the same as explicitly writing RenderView(’About’).
  • Introduced a new IActionFilter interface for action filters. ActionFilterAttribute implements IActionFilter.
  • Action Filters now have four methods they can implement representing four possible interception points.
    • OnActionExecuting which occurs just before the action method is called.
    • OnActionExecuted which occurs after the action method is called, but before the result is executed (aka before the view is rendered in common scenarios).
    • OnResultExecuting which occurs just before the result is executed (aka before the view is rendered in common scenarios).
    • OnResultExecuted which occurs after the result is executed (aka after the view is rendered in common scenarios).
    • NOTE: The OnResult* methods will not be called if an exception is not handled during the invoking of the OnAction* methods or the action method itself.
  • Added a MapRoute extension method (extension on RouteCollection) for use in declaring MVC routes in a simpler fashion.

NOTE: It is pretty easy to update existing Controller classes built with Preview 2 to use this new pattern (just change void to ActionResult and add a return statement in front of any RenderView or RedirectToAction helper method calls).

Routing changes since Preview 2

  • URLs may contain any literal (except for /) as a separator between URL parameters. For example, instead of {action}.{format} you can now have {action}-{format}. For more details on changes, see this post.
  • Routing is ignored for files that exist on disk by default. This can be overriden by setting the RouteTable.Routes.RouteExistingFiles property to true (it is false by default).

Tags: ,

Posted in ASP.NET | kick it on DotNetKicks.com | Bookmark | View blog reactions | 2 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 11th, 2008

Creating a Facebook Application using MVC

Facebook has been growing in popularity ever since it was released on February 4th 2004 at an almost unstoppable pace. Up until May 24th, 2007, it wasn’t much different than MySpace (or insert your favorite social network here), however on that day they rolled out a SDK that turned Facebook from a destination website to a platform that let any developer interact with their almost 71 million users. You can read more about the history of Facebook at Wikipedia.

My focus today isn’t on how to develop your first Facebook application in ASP.NET, because there are already many great articles on that, and even some starter kits. My focus is going to be on developing your first Facebook application with ASP.NET MVC, however this article will assume that you have the basic understand FBML (Facebook Meta Language) and MVC. If you do not have one or the other don’t worry, both are very easy to pick up on, and both have a very active developer community to answer questions.

So now that, that is out of the way lets start looking at what we need to make your MVC application in to a Facebook compatible application. The first thing you will need is the Facebook Developers Toolkit which is free on CodePlex. The second thing you will need is my Facebook MVC Web Controls which is a modification of the tookit’s Facebook.WebControls.dll made specifically for MVC. The third thing you need is ASP.NET MVC Preview 2 which is also available for free on CodePlex.

My tookit extension consists of the following classes, that mimic the current classes already in Facebook Developers Toolkit:

  • CanvasFbmlViewPage
  • CanvasFbmlViewPage<TViewData>
  • CanvasFbmlViewMasterPage
  • CanvasFbmlViewMasterPage<TViewData>
  • CanvasIFrameViewPage
  • CanvasIFrameViewPage<TViewData>
  • CanvasIFrameViewMasterPage
  • CanvasIFrameViewMasterPage<TViewData>

Facebook IFrame Application

I will start with the IFrame stuff since that is very easy and doesn’t require FBML knowledge. To create a Facebook IFrame application just follow the directions at Facebooks Getting Started Website for an IFrame. Then create an MVC Preview 2 application in Visual Studio. Then change the following in the CodeBehind for each of your pages.

public partial class Index : ViewPage

to

public partial class Index : CanvasIFrameViewPage

That is all you have to do to get Facebook working with your MVC application through IFrames. You don’t need to change your HTML because you site is going to render through an IFrame so there is no processing that is done in regards to UI rendering for Facebook. This has some drawbacks including not having the familiar Facebook interface, however this is the easiest way to get running on a Facebook app.

Facebook FBML Application

Creating the C# part of an FBML application for MVC is just as easy creating creating the IFrame application.

public partial class Index : ViewPage

to

public partial class Index : CanvasFbmlViewPage

Nothing spectacular there. Before we get started with the FBML application there is a tool that shows you what your FBML will look like when rendered out to HTML. However the real power of MVC is about to shine when we create a simple Facebook application using FBML and the ASP.NET MVC framework. Basically I took the default MVC application and modified the Index.aspx page to look like this.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="MvcFootprints.Views.Home.Index" %>
<div style="padding: 10px">
    <h2>Hi <fb:name firstnameonly="true" uid="<%= this.FBService.UserId %>" useyou="false" />!</h2>
    <form method="post" action="http://apps.facebook.com/coderjournal/">
        Get friend:
        <fb:friend-selector idname="friend" />
        <input value="find" type="submit" />
    </form>
    <hr />
    <fb:if-can-see uid="<%= Request.Forms["friend"] %>”>
    <div style=”clear: both; padding: 3px;”>
        <fb:profile-pic style=”float: left;” uid=”<%= Request.Forms["friend"] %>” size=”square” />
        <fb:name uid=”<%= Request.Forms["friend"] %>” capitalize=”true” />
    </div>
    </fb:if-can-see>
</div>

This isn’t very spectacular, all that it does it provide a friend list drop down, and submit it back to get their picture and name. But it gives the basic idea how to inner-mix FBML markup like <fb:name /%gl; and HTML with MVC. So basically that is your first Facebook application with MVC, nothing to it right?

That is really the beautiful thing about MVC, it makes writing simple applications that much simpler than ASP.NET Web Forms because you don’t have to deal with controls and it is encouraged to do processing inline with your markup. Happy coding. As always you can find the source code to this and my other projects in Coder Journals Source Control Repository.

Tags: , , , ,

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

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 16th, 2008

Is MVC Right For Your Application?

There is a simple way to tell if you can use MVC in your web application.  If any of the following are true, you probably shouldn’t:

  1. You require the ViewState
    This includes any 3rd party control…  Quick way to check this is disable ViewState and check to see if you application works as expected.
  2. You require post backs
    This usually is required by Web Forms or Microsoft AJAX Toolkit…  Fortunately most of the post back functionality can be duplicated on the client side with AJAX.  I fine jQuery makes a real easy job of this.

So that is all that you need to ask your self when thinking of upgrading or deciding which route to take when planning your new application.

Tags: , , , ,

Posted in ASP.NET, Programming | kick it on DotNetKicks.com | Bookmark | View blog reactions | No 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 »

March 9th, 2008

ASP.NET MVC Preview 2 CAPTCHA using ActionFilterAttribute

My last article on ASP.NET MVC CAPTCHA was very well received by many of my readers and it even caught the eye of the DotNetKicks crowd. Now that MVC Preview 2 was released last week, many new features make encapsulating my CAPTCHA control even easier. Most notably is the ActionFilterAttribute which allows you to override the Pre and Post action events for any action the attribute is applied to.

Basically everything works the same as it did in the previous article. I just modified things for MVC Preview 2. To validate the CAPTCHA you add the attribute CaptchaValidation to the action.

[CaptchaValidation("captcha")]
public void Register(string userName, string password, string email, string question, string answer, bool captchaValid){
    // do stuff
}

You still need to register the CAPTCHA image handler.

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

I added an extension to HtmlHelper that generates a text box with autocomplete=”off”.

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

Which generates the following.

Example of CAPTCHA

You can view the source code for this on my Google Code Project, everything is available through SVN.

  1. CaptchaValidationAttribute.cs
  2. CaptchaHelper.cs
  3. CaptchaImage.cs
  4. CaptchaImageHandler.cs

Or you can download the project for you own personal use.

Tags: , , , ,

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

March 3rd, 2008

ASP.NET MVC CAPTCHA

Note: Most recent update for MVC Release Candidate 3 is out.

So my MVC application that I have been working on required a CAPTCHA today. The problem is that all of the solutions out there, that I could find for ASP.NET, are control based and I wanted a more MVC approach. I know I could have easily implemented one of them using the Html.RenderControl(), however I want to use a MVC approach to the CAPTCHA authentication box. So I started out with Jeff Atwood’s CAPTCHA Control made for ASP.NET 2.0 in VB.NET 2005. I then converted it to C# and modified and expanded on it for the MVC framework. The following is the result of my work.

The following creates the CAPTCHA image on the page, that looks like the image below the code:

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

Example of CAPTCHA

The following is how the CAPTCHA is validated:

[ControllerAction]
[CaptchaValidation("captcha")]
public void Register(string userName, string password, string email, string question, string answer, bool captchaValid)
{
	// do stuff
}

The input in the CaptchaValidationAttribute is the name of the form field that you want to check against the CAPTCHA. Also notice the last parameter of the method called captchaValid this is required, and the value contains information on if the CAPTCHA was validated or not. captchaValid is automatically inserted in to the route data. From there you can go on and redirect the user to another page or do whatever your application would require if the CAPTCHA failed validation.

So as you can see it is relatively simple to use the CAPTCHA validation that I have created to test and verify your input with a CAPTCHA. The setup just requires adding a HttpHandler to the Web.config and the inclusion of a couple files.

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

All the work is actually done in the OnPreAction method in the Controller like so:

protected override bool OnPreAction(string actionName, System.Reflection.MethodInfo methodInfo)
{
	object[] attributes = methodInfo.GetCustomAttributes(typeof(CaptchaValidationAttribute), false);

	if (attributes != null && attributes.Length > 0)
		OnCaptchaValidation(actionName, methodInfo, (CaptchaValidationAttribute)attributes[0]);

	return base.OnPreAction(actionName, methodInfo);
}

protected virtual bool OnCaptchaValidation(string actionName, System.Reflection.MethodInfo methodInfo, CaptchaValidationAttribute attribute)
{
	if (attribute == null)
		throw new ArgumentNullException(”attribute”);

	// make sure the captcha valid key is not contained in the route data
	if (this.RouteData.Values.ContainsKey(”captchaValid”))
		this.RouteData.Values.Remove(”captchaValid”);

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

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

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

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

	// validate the captch
	if (String.IsNullOrEmpty(actualValue) || String.IsNullOrEmpty(expectedValue) || !String.Equals(actualValue, expectedValue, StringComparison.OrdinalIgnoreCase))
	{
		this.RouteData.Values.Add(”captchaValid”, false);
		return true;
	}

	this.RouteData.Values.Add(”captchaValid”, true);
	return true;
}

And with the following HtmlHelper:

public static string CaptchaImage(this HtmlHelper helper, int height, int width)
{
	CaptchaImage image = new CaptchaImage {
		Height = height,
		Width = width,
	};

	HttpRuntime.Cache.Add(
		image.UniqueId,
		image,
		null,
		DateTime.Now.AddSeconds(ManagedFusion.Web.Controls.CaptchaImage.CacheTimeOut),
		Cache.NoSlidingExpiration,
		CacheItemPriority.NotRemovable,
		null);

	StringBuilder stringBuilder = new StringBuilder(256);
	stringBuilder.Append("<input type=\"hidden\" name=\"captcha-guid\" value=\"");
	stringBuilder.Append(image.UniqueId);
	stringBuilder.Append("\" />");
	stringBuilder.AppendLine();
	stringBuilder.Append("<img src=\"");
	stringBuilder.Append("/captcha.ashx?guid=" + image.UniqueId);
	stringBuilder.Append("\" alt=\"CAPTCHA\" width=\"");
	stringBuilder.Append(width);
	stringBuilder.Append("\" height=\"");
	stringBuilder.Append(height);
	stringBuilder.Append("\" />");

	return stringBuilder.ToString();
}

The rest of the source can be downloaded, if you are interested:

I have tested this to work with in the guidelines that I need, which are pretty broad. However if you find a circumstance where this won’t work please let me know and I would be happy to integrate it in to this code.

Update (2008-3-9): The latest refresh of my ASP.NET MVC CAPTCHA control for Preview 2 of the MVC framework using ActionFilterAttribute.

Tags: , , ,

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

February 27th, 2008

ASP.NET MVC Route Validation and SEO

Recently I have been using the ASP.NET MVC framework for a project at work. And one of the requirements was that certain data inputed in to the URL be tightly verified. I originally thought that data was verified by the type specified in the ControllerAction, however I came to find out that it wasn’t. So if you have say a page number and the user enters a letter in the URL the application just proceeds on it’s marry way. For example on the Kigg site:

  1. http://kigg.dotnetslackers.com/Story.mvc/Category/Lifestyle/1
  2. http://kigg.dotnetslackers.com/Story.mvc/Category/Lifestyle/a
  3. http://kigg.dotnetslackers.com/Story.mvc/Category/Lifestyle/
  4. http://kigg.dotnetslackers.com/Default.aspx

I am not sure yet if this is because Kigg is implemented with a int? and any failure of the parsing results in a null. But that wouldn’t explain the 3rd result in which Kigg returns the category as if it was the 4th result. I would expect that the 3rd result should return the same results as the 1st result. This setup can results in many SEO issues where I can inject keywords in to the URL with malicious intent and still have it resolve correctly. For example:

  1. http://kigg.dotnetslackers.com/Story.mvc/Category/Lifestyle/coderjournal

So my recommendation to my readers is to also implement a URL Rewriter to force normalization on to the MVC URLs. I am personally using my own URL Rewriter on this project that I am creating to better control my inputs, by providing type validation, into my application. At the very least use the built in verification and don’t put null in the defaults.

RouteTable.Routes.Add(new Route {
	Url = "[controller]/[action]/[page]“,
	Defaults = new { controller = “Home”, action = “Index”, page = 1 },
	RouteHandler = typeof(MvcRouteHandler),
	Validation = new { method = “GET”, page = “[0-9]+” }
});

The Validation property that you see on the last line above allows the type of HTTP Method allowed POST or GET usually. And the other properties are similar to what you do with the Default only they are RegEx statements that validate the specific part of the URL.

Really what I would like to see from ScottGu and the rest from the MVC framework is a more extensible Route object or RouteTable. I was really surprised that I wasn’t able to overload the handling of the URL in the MVC framework. Don’t get me wrong the team has done a great job hitting 95% of the potential needs of the development community. However if you fall in that 5% you are either out of luck, or forced to create a new Module, Controller, RouteTable, Route, and a whole host of supporting objects. For instance if I wanted to give the users of my URL Rewriter and Reverse Proxy a common interface that they can both do their advanced URL Rewriting and Reverse Proxying and their MVC Action/Controller setup. I wouldn’t be able to do it unless I basically reimplemented the URL handling of the MVC framework. I might end up doing that in the future, but I will probably wait until the Gold Version of MVC is released. If this was a perfect world I would probably implement some syntax in my URL Rewriter Rules file that looked like:

# if not feed burner requesting
RewriteCond %{HTTP_USER_AGENT} !^FeedBurner.*$
# rearrange old structure
RewriteRule ^/<?'controller'([a-z]+)>/index.html$  /$1/List/page$2.html [C]
# in to new MVC model
RewriteRule ^/<?’controller’([a-z]+)>/<?’action’([a-z]+)>/page<?’page’([0-9]+)>.html$  {controller=”Home”,action=”List”,page=1} [MVC,NC,L]

But that is just me making a wish for the future of MVC extensibility. All that I would need to accomplish this task is a little more flexibility in the URL handling. If anybody from the MVC wants to talk to me more about my requirements please feel free to contact me.

Really the last thing, I imagine, that the MVC team would want to cause is more SEO problems than are already created by uneducated developers.

Tags: , , , ,

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