One of the hokey things about the OpenIdPortableArea is that the ProvidersWidget contains some hard coded CSS, JavaScript, and Urls to images on the Internet.  Steve Michelotti pushed a change to MvcContrib that provides a way to resolve embedded static resources.  Since the OpenIdPortableArea project could really use this feature, I eagerly downloaded it and tried it out.  Here are my thoughts…

Getting the EmbeddedResourceController hooked up isn’t terrible.  First I compiled the MvcContrib source, and then dropped in & re-added a reference to the MvcContrib.dll.  Then, in my PortableArea project I added the following route to the OpenIdAreaRegistration:

context.MapRoute(

    "OpenId-EmbeddedResource",

    "OpenId/Content/{resourceName}",

    new { controller = "EmbeddedResource", action = "Index" },

    null,

    new string[]{ "MvcContrib.PortableAreas" }

);


One of the tricky things to remember is to include the namespace parameter of “MvcContrib.PortableAreas” while mapping the route.  Without this, the routing engine won’t find the controller properly.

After wiring up this route I added a providers.css file and embedded it.

image

Then, I updated the reference in the ProvidersWidget:

<link href="/OpenId/Content/content.styles.providers.css" rel="stylesheet" type="text/css" />


This works!  However, you may have noticed that the Url for the CSS file includes “content.styles.providers.css”.  This is due to the way MvcContrib currently resolves static resources.  All embedded resources are registered by their namespace, or location within the project.  While this isn’t a big deal, it can be somewhat limiting.  I would like to have a little more control over what the route to this embedded resource will look like, but what other options are there?

If I were to choose a route for the OpenId providers.css file, I think it would look something like:

<link href="/OpenId/Styles/providers.css" rel="stylesheet" type="text/css" />


In order to use a Url like that, the providers.css file would have to be located under OpenIdPortableArea.OpenId.  I might have lots of resources, though.  It would be tidier to keep them in their own folder.  Time to be creative.

The EmbeddedResourceController has an Index method that takes a string parameter called “resourceName”.  This parameter is eventually used to resolve the embedded resource based on its namespace.  Unfortunately, there’s no way to help MvcContrib find the correct namespace for the desired resource through routing alone.  To solve this problem, I used simple inheritance.

public class StylesController : EmbeddedResourceController

{

    public ActionResult Resource(string resourceName, string resourceLocation)

    {

        return Index(string.Format("{0}.{1}", resourceLocation, resourceName));

    }

}


I created a new Controller called Styles, and inherited from EmbeddedResourceController.  It has one action method called Resource.  The method takes two parameters: “resourceName” and “resourceLocation”.  It uses the parameters to build the resource’s actual name.  Inheriting from EmbeddedResourceController buys us the ability to call the Index action with the proper resource name.

Finally, a new route can be implemented (which is actually simpler):

context.MapRoute(

    "OpenId-StylesResource",

    "OpenId/Styles/{resourceName}",

    new

    {

        controller = "Styles",

        action = "Resource",

        resourceLocation = "Content.Styles"

    }

);


This new controller gives us the opportunity to adjust the resource name, as well as the freedom to organize embedded static resources the way we want inside of our portable areas.  Perhaps the EmbeddedResourceController could be expanded to incorporate this point of extensibility.

Tuesday, April 13, 2010 12:58:40 AM (Eastern Daylight Time, UTC-04:00)  #    Comments [0] -
Embedded Resources | MvcContrib | OpenIdPortableArea | Portable Areas
Comments are closed.

John Nelson

mugshot I am a passionate C# Developer working in ASP.NET on an e-commerce solution for ticketing software. I work across all of the application layers, including server side functionality, and client side programming with jQuery and MS Ajax. Although my full time job is in WebForms, I spend many of my off hours working with MVC. I am especially interested in productivity and good programming practices.

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2010
johncoder.com
Statistics
Total Posts: 41
This Year: 17
This Month: 0
This Week: 0
Comments: 4