Tag archive for 'mvc'

27
Apr

Localizing MVC for ASP.NET views and master pages

Microsoft's MVC for ASP.NET is still under serious development but at the moment support for localization is a little weak. Here's one approach that works with the 04/16 source-drop.

LocalizingWebFormViewLocator class

This class helps by trying to identify language-specific versions of views, user controls and master-pages where they exist, falling back to the generic one where necessary.

public class LocalizingWebFormViewLocator : ViewLocator
{
	public LocalizingWebFormViewLocator() : base()
	{
		ViewLocationFormats = new[] { "~/Views/{1}/{0}.{2}aspx", "~/Views/{1}/{0}.{2}ascx",
			"~/Views/Shared/{0}.{2}aspx", "~/Views/Shared/{0}.{2}ascx" };
		MasterLocationFormats = new[] { "~/Views/{1}/{0}.{2}master", "~/Views/Shared/{0}.{2}master" };
	}

	protected override string GetPath(RequestContext requestContext, string[] locationFormats, string name)
	{
		string foundView = FindViewLocation(locationFormats, requestContext, name, CultureInfo.CurrentUICulture.Name + ".");
		if (String.IsNullOrEmpty(foundView))
			foundView = FindViewLocation(locationFormats, requestContext, name, "");
		return foundView;
	}

	protected string FindViewLocation(string[] locationFormats, RequestContext requestContext, string name, string cultureSuffix)
	{
		string controllerName = requestContext.RouteData.GetRequiredString("controller");
		foreach (string locationFormat in locationFormats) {
			string viewFile = string.Format(CultureInfo.InvariantCulture, locationFormat, name, controllerName, cultureSuffix);
			if (HostingEnvironment.VirtualPathProvider.FileExists(viewFile))
				return viewFile;
		}
		return null;
	}
}

Using the class

To use the class you must set the ViewLocator on the WebFormViewEngine to a new instance of LocalizingWebFormViewLocator (either in the constructor or in your common controller subclass) and ensure that any master pages are specified on the RenderView calls to ensure the localized version is detected.

public class HomeController : Controller
{
	public HomeController() {
		((WebFormViewEngine)ViewEngine).ViewLocator = new LocalizingWebFormViewLocator();
	}

	public ActionResult Index() {
		return RenderView("Index", "Site");
	}

	public ActionResult About() {
		return RenderView("About", "Site");
	}
}

You must also ensure the thread's current UI culture is set. The easiest way to do this is to specify the following in your web.config file's system.web section which will pick it up automatically from the user's browser settings via the HTTP language-accept header.

<globalization responseEncoding="UTF-8" requestEncoding="UTF-8" culture="auto" uiCulture ="auto" />

MVC for ASP.NET default page in pseudo-Japanese via the Babelfish
Then all you need to do is create views and master pages that have the culture name appended between the name and .aspx, e.g:

/Views/Home/Index.aspx (common fall-back for this view)
/Views/Home/Index.ja.aspx (Japanese view)
/Views/Home/Index.en-GB.aspx (British English view)

/Views/Shared/Site.Master (common fall-back for this masterpage)
/Views/Shared/Site.ja.Master (Japanese masterpage)

Caveats

There are some limitations to this solution:

Only primary language is attempted

Only the user's primary language specified in their browser is attempted despite browsers having a complete list in order of preference. Ideally we would scan down this entire list before giving up but that would need more code and there is the issue of whether scanning for several languages across several folders could be too much of a performance hit.

Specifying the masterpage on RenderView

It would be nice if you didn't have to specify the masterpage on renderview but if you do not then the ViewLocator never gets called to resolve the actual masterpage address. This may be for backward compatibility within MVC.

Creating files in Visual Studio

Visual Studio 2008 seems to get a little confused if you create a Index.ja.aspx or Site.ja.aspx - whilst the files are created okay the names are not and you will need to adjust the class names to ensure they don't conflict and make sure the opening declaration on the .aspx file points to the right code-behind page and inherits from the correct name.

Of course the beauty of this approach is you can mix-and-match using dedicated views where required and localising labels in the fall-back view when it isn't.

[)amien

31
Jan

The pragmatic .NET developer

Long-time friend, fellow co-host of the GSDF and the coding genius behind the open-source Ogre3D engine Steve Streeting has written an interesting piece on Open source adoption; countering the fear and doubt. I have no doubt that this was fuelled by a lengthy discussion last night in the Ship & Crown pub - a common ritual after our GSDF meetings.

The reasons why I adopted .NET as my primary platform despite being tied to a single-supplier are:

  • Ease of deployment & set-up
  • Low resistance to adoption
  • Great tool integration
  • Official & community support
  • Love for C# and the CLR

The ALT.NET movement

Many .NET developers are reluctant to look wider afield but this is not exclusively the case and a person focused on the .NET platform but open to selecting beneficial alternatives to the Microsoft prescription is exactly what the ALT.NET moniker was coined to encapsulate.

SourceForge lists over 6,000 open-source C# projects alone and many well-known open source Java & PHP projects have made their way to the .NET platform. NHibernate, NUnit, NCover, Spring.NET & DotNetNuke alongside new .NET developments such as xUnit.NET, SubSonic, Subtext etc.

Best of breed

Where a non-Microsoft option is functionally superior or more cost effective I will consider it whether it is proprietary or open source.

I do not however select a solution simply because it is considered the "best of breed" at that particular moment. Integration, training, availability of support and experienced developers, deployment, cost, barriers to entry and roadmaps must be taken into account.

Given that Microsoft provide the .NET platform anything 'in-the-box' scores highly in many of these areas.

Sometimes a non-Microsoft solution comes out on top or there is a compelling reason to adopt it anyway. This is why my toolkit already contains Subversion, TortoiseSVN, AnkhSVN, Reflector and NUnit.

It's also why I currently run Mac OS X alongside Vista, use WordPress as my blogging platform, prepare my presentations with KeyNote and use OmniFocus to organise my life.

Robust alternative projects

I have concerns about longevity and support on projects from companies and hobbyists regardless of whether they are open source or proprietary.

NDoc, CVS & NullableTypes are three I've used which died when an alternative commercial or open source project gained more momentum and SourceForge is seemingly littered with thousands of dead projects.

If a project you rely upon dies you have one of a number of options:

  1. Migrate to something new (gained little from open source)
  2. Fix bugs and problems yourself (time spent working outside your business domain)
  3. Have a support contract with somebody else to work on it (single-supplier scenario?)

Competition is important

Competition is important but I can not, in a professional capacity, recommend to customers something that I believe is less suitable in the interest of keeping the competition healthy.

Confusion about choice

I hit this one first hand developing my final-year degree project which required development of a web site in Java.

The number of choices for Java was incredibly confusing despite knowing the syntax. J2SE or J2EE? JSP, Struts, Spring or another servlet package? What about the database and ORM? Application server? What versions work together? What overlaps? Would I be able to get experienced developers? If not how long to train them up?

.NET has many options too but I can start with the .NET Framework and get right into solving the domain problem. If the going gets tough I may have taken a wrong turn and need a different solution. That could involve choosing an alternative component or framework but now I'll know what problem I'm trying to solve when I go looking.

Developers on complex projects felt that WebForms wasn't ideal - it is hard to maintain, the output bloated with leaky implementation (ViewState) but it serves many developers well enough.

Open-source projects such as MonoRail addressed this taking cues from Ruby on Rails. Microsoft acknowledge this and add a similar MVC framework going so far as to support additional engines and components allowing elements of MonoRail to be used. Those guys could drop the glue required to get their engines into the pipeline and just concentrate on engines if they wish.

What works for me

Stay small and focused until you feel friction.

Friction isn't always technical or immediately obvious. It might be future plans and it's often people. It might be what isn't there and will never be.

Time lost on friction is not spent developing your domains features.

If another solution causes less friction, use it but don't underestimate unknowns.

I guess that's just being pragmatic.

[)amien

19
Sep

Castle Project & MonoRail concerns

I really want to like MonoRail but I find it difficult to feel the love no matter how much I desire Rails-like features without the scalability issues and unusual syntax/learning curve of Ruby.

Here's my list of concerns:

Slow release cycle

The current release is 1.0 RC2 which was released November 1, 2006. That's some 10 months ago and yet we have no RC3 or final release.

Part of the hold-up seems to be trying work out what to include and exclude, which brings me onto my next point...

Abandoning convention over configuration?

One guiding principle behind Ruby on Rails is Convention over Configuration. This means that instead of allowing you to configure everything to the nth degree a single 'conventional' approach is taken..

This results in an gentler learning curve with less to configure and is generally part of KISS.

The Castle Project's take on this philosophy is a little off by providing you with a combination of view engines and IoC interfaces to chose from.

In the case of view engines neither NVelocity or Brail support C# or VB.NET which does mean you need to learn another language for writing your views and loose syntax highlighting and IntelliSense in the process.

If I was prepared to accept all that I might as well switch to Ruby on Rails.

The WebForm view engine supports C# but has a number of limitations and uses what I was trying to get away from in the first place (WebForms).

Ken Egozi has come up with a C# based view engine that avoids WebForms confusingly named AspView.

With Inversion of Control whether you use the MicroKernel directly or the Windsor Container wrapper is up to you and I hope you figure out which to use better than I did.

Castle Project web site

Looks good however needs better maintenance/management:

  • Wiki contains spam (FAQ, Tutorial, Tips and Tricks etc.)
  • Samples download returns a 404 not found
  • Enabling Inversion of Control is an empty stub yet is linked from the main intro page

I couldn't find anything about how navigation/site maps are managed.

Going forward

Castle Project say their projects are independent and they should consider breaking them into separate downloads with individual release cycles to keep the pieces moving independently and competitively.

MVC alternatives

Microsoft are working on an MVC engine for ASP.NET themselves. Whilst Microsoft's track record with user interface tool kits is less than spectacular the recent work with LINQ and knowing that both Scott Guthrie and now Phil Haack are on the team inspires more confidence.

Until they release a CTP and a timetable however this can't be seriously considered especially for projects that need to start soon. I'm hoping we'll see a similar cycle to the AJAX and Control Adapters where early access & final versions were available that hooked in to currently shipping versions of .NET and Visual Studio so that we're not waiting for .NET 4.0.

RC3 was released the following day. Check out the contents or download it.

[)amien




Feed subscription

Subjects