Tuesday, November 6, 2012

Tips for ASP.NET MVC 4: lowercase URLs

A small article about a new feature in ASP.NET MVC 4: the new LowercaseUrls property... (not exactly a new feature of ASP.NET MVC 4: the routing is a part of the .NET Framework itself. The LowercaseUrls property is available in all the projects which use .NET 4.5, whether it’s ASP.NET MVC 3 or ASP.NET MVC 4...)

The problem with ASP.NET MVC is that URLs generated thanks to the routing mechanism are based on the controller and action names. These will typically be resulting in URLs like /Account/Login, etc.
But the routing mechanism is not case-sensitive and a request to account/login works just the same.
It's not a good practice for the SEO to allow URLs with any casing because it could technically be considered to be duplicate pages with the same content.

Usage is very simple, just set the property like in the following code:

   1:  public static void RegisterRoutes(RouteCollection routes)
   2:  {
   3:      ...
   4:      routes.LowercaseUrls = true;
   5:      ...
   6:  }

You can test the modification with a simple action link:

   1:  @Html.ActionLink("Home", "Index", "Home")

An you will see this result:

   1:  <a href="/home/index">Home</a>

You don't have to worry about the capital letters in your URLs but this is not a reason to forget some good SEO practices: you can see some tips here.

Sunday, October 28, 2012

Programmatically remove HTTP response headers

By default, all the responses of your server will be sent with some embarrassing details...

For an ASP.NET MVC web application, you have these headers :

  • Server: which is added by IIS.
  • X-AspNet-Version: which is added at the time of Flush in HttpResponse.
  • X-AspNetMvc-Version:which is  added by MvcHandler in System.Web.dll.
  • X-Powered-By: which is added by IIS.

Hackers will be happy to know the exact version of the used Framework: if your server has not been updated for a while and a major security vulnerability was found for the version of the Framework you are using, you will help them...

Moreover, these headers add a weight to all your responses (a few bytes, but I like optimizing...)

If you want to remove these headers, here are the steps to follow:

1) Removing the Server header: go to Global.asax.cs, add the Application_PreSendRequestHeaders event with this code:

   1:  protected void Application_PreSendRequestHeaders(object sender, EventArgs e)
   2:  {
   3:      var app = sender as HttpApplication;
   4:      if (app == null || !app.Request.IsLocal || app.Context == null)
   5:          return;
   6:      var headers = app.Context.Response.Headers;
   7:      headers.Remove("Server");
   8:  }

2) Removing the X-AspNetMvc-Version header: go to Global.asax.cs, modify the Application_Start event with this code:

   1:  protected void Application_Start()
   2:  {
   3:      ...
   4:      MvcHandler.DisableMvcResponseHeader = true;
   5:      ...
   6:  }

3) Removing the X-AspNet-Version header: edit the web.config and add this element in the system.web section:

   1:  <system.web>
   2:      ...
   3:      <httpRuntime enableVersionHeader="false" />
   4:      ...
   5:  </system.web>

4) Removing the X-Powered-By header: edit the web.config and add this code in the system.webServer:

   1:  <system.webServer>
   2:      ...
   3:      <httpProtocol>
   4:          <customHeaders>
   5:              <remove name="X-Powered-By" />
   6:          </customHeaders>
   7:      </httpProtocol>
   8:      ...
   9:  </system.webServer>

The work is done, the responses of your server will be lighter and will not give important information about its versions.

Saturday, October 27, 2012

Donut Caching with ASP.NET MVC 4

I'm working on a new personal project during my free time and I chose to develop it with ASP.NET MVC 4 (hosted on Azure of course...) to test the new features of this version.

In this project, I need to display "Logged in as xxxx " (if the user is logged...) in the header of the page. This is a simple scenario to implement but caching could complicate the development of my web app...

My header is in my layout and is used everywhere but I would like to place an OutputCacheAttribute on some actions (the home page, etc.). If I put the attribute on an action, all of my users will see an header with "logged in as xxxx" of the first incoming query!

The solution to this problem is named "Donut Caching": you send a cached page from the server with a "fresh" portion which is not in cache (the donut's hole).
Concretely, the server does not generate the requested page (query the DB, etc.): it just needs to take the cached version and replace a specific part.

Luckily, you do not need to develop your own custom OutputCacheAttribute because there is already a very good package (There's An App A Pack For That... thanks NuGet!): MvcDonutCaching for ASP.NET MVC 3 and later...

To install the package, you can search through NuGet or directly type the following command in the "Package Manager Console":

   1:  install-package MvcDonutCaching

The use of this package is very simple... They have created several extension methods for HtmlHelper with the usual parameters plus another boolean parameter: excludeFromParentCache. I just have to call my partial view (with the "connected has xxxx"...) like that:

   1:  ...
   3:  @Html.Action("LoginHeader", "Account", new { lang }, true)
   5:  ...

The last parameter of Html.Action is set to true: this partial view will be excluded from the parent cache (if there is a cache on the action...). (do not pay attention to new { lang }, it's a route's value)

To make it work, you must not use the OutputCacheAttribute but the DonutOutputCacheAttribute:

   1:  [DonutOutputCache(Duration = 60, VaryByParam = "lang")]
   2:  public ActionResult Index(string lang)
   3:  {
   4:      ...
   6:      return View();
   7:  }

And that's it! The first request will be cached during 60 seconds but the LoginHeader partial view will be generated every time.

(note: of course, the donut caching only works on the server side...)

Sunday, September 16, 2012

BemyApp : Kings’ Night at Paris

I participated to the BeMyApp "King's Night" last Friday in Paris: it was an event for Windows 8 development (C#/XAML, JS/HTML or C++) throughout the night ... There were some pizzas, beers, burgers, massages, ice creams, etc..

I am very happy to have been there and the developer community of Paris is very nice! Here are some pictures of the event (sorry for the quality, it was dark) ...

Thank you for your welcome, parisian guys!

Tuesday, April 3, 2012

Facebook C# SDK and logout on Windows Phone

(Facebook C# SDK version:

Most tutorials explain how to connect to Facebook for a Windows Phone application... But the logout is rarely mentioned while it is a very important feature for the users of your application.

So, how can you propose the possibility of logout to your users? We suppose that you already have a WebBrowser used for the login: we will call it "FacebookWebBrowser".

To make a logout from this WebBrowser, you just have to do that:

   1:  FacebookWebBrowser.Navigate(new Uri(String.Format("https://www.facebook.com/logout.php?next={0}&access_token={1}", _loginUrl, _accessToken)));

The _loginUrl comes from the "GetLoginUrl" method (from the Facebook C# SDK) and the _accessToken comes from a previous login on Facebook.

Nothing complicated but very useful to know!

Saturday, March 10, 2012

SPUpgradeException was thrown

I was trying to install SharePoint Server 2010 on my laptop which runs Windows 7 x64 and the configuration failed at the second step:
Exception: Microsoft.SharePoint.Upgrade.SPUpgradeException: Failed to call GetTypes on assembly Microsoft.Office.Server.Search
The error does not help you a lot... But the problem occurs if your Windows 7 does not have the Chart Control installed.

You just have to quit the configuration wizard and to download the Chart Control here. You can now restart your configuration wizard, this should work better now!

Monday, March 5, 2012

Could not load file or assembly 'msshrtmi' or one of its dependencies

Today, for no reason, one of mine projects in ASP.NET MVC 3 crashed at launch... I had this error every time:

After some searches, I've found the solution:

  • unload your web project
  • edit the .csproj file
  • remove all "PlatformTarget" elements that you found
  • reload your web project

Normally, it should be enough but I have also changed my build configuration to x64 (inspite of Any CPU).

Hope that information can be useful for someone!

Saturday, February 25, 2012

Route for ASP.NET website and php attacks

When you have a website online, it is common that it is attacked by bots. Most of the time, these attacks aim a php website... And since these robots do not know that my site is in ASP.NET MVC, it suffers for their attacks... As you can see in the next image, my RSS feed (from Elmah (think to visit this site if you are using Elmah : http://asafaweb.com/)) has a lot of errors due to some attacks:

Each attack throws an exception and my logs are unnecessarily cluttered... For this reason, I've had a new route in my Global.asax.cs file:

   1:  routes.MapRoute(
   2:      "PhpAttack",
   3:      "{*allphp}",
   4:      new { controller = "Error", action = "PhpAttack" },
   5:      new { allphp = @".*\.php" }
   6:  );

(note: think to put the page "PhpAttack" in cache)

You can handle these attacks according to your inspiration... For my part, I chose to insert an iframe with a "let me google that for you" link:

   1:  <iframe frameborder="0" src="http://lmgtfy.com/?q=how+to+hack+php" width="100%" height="550px"></iframe>

A little bit more fun than my cluttered RSS feed with useless errors !

Sunday, February 19, 2012

Issue with circular navigation in Windows Phone 7

The good management of the back button is really important: for example, a valid application must quit when you press the back button when you are on its start page. Other constraints must be respected like when you press the back button when a dialog is open (like a ListPicker control), you have to cancel the back behaviour and close the dialog...

For some applications, there's not necessary to think about it because the default behavior is well suited. But for other applications, it will sometimes be necessary to make some changes.

I will show an example of my application (Blind Friends)... If an user wants to play, he will go through these pages:

> >

Imagine that the user presses the "back to main menu" at the end of the game, I'll use NavigationService.Navigate(Uri source) to bring him back to home. That will work but if the user presses the back button once he is on the home page, the application will go to the score page because this is the previous page in the navigation stack... My application can be validated with this issue because it must be closed when the user presses the back button on this page.

To regain the normal behaviour, I have modified the URI in NavigationService.Navigate(Uri source):

   1:  NavigationService.Navigate(new Uri("/Pages/MainPage.xaml?homeFromPageScore=true", UriKind.Relative))

And in the codebehind of my home page:

   1:  protected override void OnNavigatedTo(NavigationEventArgs e)
   2:  {
   3:      base.OnNavigatedTo(e);
   5:      if (e.NavigationMode == NavigationMode.New && NavigationContext.QueryString.ContainsKey("homeFromPageScore"))
   6:      {
   7:          NavigationService.RemoveBackEntry();
   8:          NavigationService.RemoveBackEntry();
   9:          NavigationService.RemoveBackEntry();
  10:          NavigationService.RemoveBackEntry();
  11:      }
  12:  }

With this workaround, you clean the navigation stack as many times as necessary (neither too much nor too little...). In my case, I'm sure on the number of time I have to remove an element in the navigation stack and the behaviour requested by Microsoft is respected.

Saturday, February 18, 2012

Issue with Chinese (zh) and Windows Phone

(FYI: I'm speaking about the Windows Phone SDK 7.1, these information can change...)

For my first Windows Phone application, I had an issue with the Chinese language... In the ASP.NET MVC version, I use a resource file like this BlindFriendsResource.zh.resx and that works!

So I wanted to keep the same file for the mobile version and... the application was launched in its default language (English).

After some research, I found the solution! I created two files: BlindFriendsResource.zh-CN.resx (Simplified) and BlindFriendsResource.zh-TW (Traditional). These two files correspond to the both supported  languages in Windows Phone.

Using "zh" only will not work for the Chinese language but using "fr" will work for a belgian  person (French speaker: fr-BE) or a french person (fr-FR)... So, finaly, you can see here the list of my resources files:

- BlindFriendsResource.resx
- BlindFriendsResource.es.resx
- BlindFriendsResource.fr.resx
- BlindFriendsResource.nl.resx
- BlindFriendsResource.pt.resx
- BlindFriendsResource.zh-CN.resx
- BlindFriendsResource.zh-TW.resx

I hope that information can be useful for someone ;-)

Tuesday, February 14, 2012

Blind Friends is now on Windows Phone 7

Blind Friends (my Facebook game) is now on Windows Phone 7 market:

I used again the Facebook C# SDK (http://facebooksdk.codeplex.com/) for this mobile application and the ASP.NET MVC version communicates with the WP7 version with some Json...

I will write one or two articles on the development of Blind Friends WP7 (Facebook logout, circular navigation issue, ...)

Découvrez le Nokia Lumia 900 avec MonWindowsPhone

Wednesday, January 25, 2012

Windows Phone 7 emulator and computer keyboard

I'm currently working on the Windows Phone version of Blind Friends and I'm using the Facebook C# SDK Framework (like the ASP.NET MVC version).

I had to debug the login page and I quickly got bored of writing my email/password in the emulator... If you have a Windows Phone device, you can enter these information with your fingers but if you debug with the emulator, you maybe want to use your computer's keyboard.

By default, the keyboard is not enabled but activating it on your development computer is easy:

  • to enable the keyboard: press the PAGE UP key (or PAUSE key)
  • to disable the keyboard: press the PAGE DOWN key (or PAUSE key, again)

It's fast and convenient, but some details may annoy you... For example, if you enable the keyboard, the emulator will not support the orientation changes. You have to disable the keyboard, and then rotate the emulator.

For more information on the keyboard mapping: http://msdn.microsoft.com/en-us/library/ff754352(v=VS.92).aspx

Tuesday, January 24, 2012

Windows Azure and Application Pool Timeouts

This article may help you if you use Windows Azure and you want your application to always responds as quickly even after a long period without use...

With default parameters, your app pool is shut down after 20 minutes of inactivity and your application will take a bit more time to respond.

You can simply change the settings if you want your application pool is never shut down:

- First step: create a new folder called "tasks" at the root of your Web Project and add a new file called "timeout.cmd" with this line of command:

   1:  %windir%\system32\inetsrv\appcmd set config -section:applicationPools -applicationPoolDefaults.processModel.idleTimeout:00:00:00

Once the file created, you need to put the "Copy to Output Directory" property to "Copy Always".

- Second step: add this into ServiceDefinition.csdef (at same level than "<Sites>", "<Endpoints>", ...):

   1:  <Startup>
   2:        <Task commandLine="tasks\timeout.cmd"
   3:              executionContext="elevated" />
   4:  </Startup>

You can find the code here: