I am attempting to impliment a custom view engine to serve mobile views based on the user agent. I am following Scott Hanselman's approach from this blog post.
I have inherited from the WebFormsViewEngine and overridden the FindView method the same way that Scott describes in his blog.
I then added a few lines to my Global.asax Application_Start method to clear the view engine collection and add a new instance of my view engine.
After some testing it would appear that MVC is ignoring my view engine. When it failed to find my custom views based on the user agent of the browser I resorted to hardcoding the custom path to to append to the view and it still managed to fall back on the default view. I set a breakpoint in my FindView method and sure enough, it's not being called at all.
How can I get my custom view engine to work? Any help will be much appreciated.
My view engine looks like this:
public class MyViewEngine: WebFormsViewEngine
{
public override ViewEngineResult FindView (ControllerContext controllerContext, string viewName, string masterName, bool useCache)
{
ViewEngineResult result = null;
//Serve a special view for iPhones
if (UserAgentIs(controllerContext, "iPhone"))
{
result = base.FindView(controllerContext, "Mobile/iPhone/" + viewName, masterName, useCache);
}
//If no special view is found, fall back to the default view
if (result == null || result.View == null)
{
result = base.FindView(controllerContext, viewName, masterName, useCache);
}
return result;
}
private bool UserAgentIs(ControllerContext controllerContext, string userAgentToTest)
{
return (controllerContext.HttpContext.Request.UserAgent.IndexOf(userAgentToTest, StringComparison.OrdinalIgnoreCase) > 0);
}
}
And in my Global.asax:
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new MyViewEngine());
}
When this setup didn't work I even tried to simplify my FindView method to this:
public override ViewEngineResult FindView (ControllerContext controllerContext, string viewName, string masterName, bool useCache)
{
ViewEngineResult result = null;
result = base.FindView(controllerContext, "Mobile/iPhone/" + viewName, masterName, useCache);
return result;
}
And that didn't work either. It still returned the default view. And yes, the view page and master page that should be found by that statement do actually exist. I'm pretty stumped as to why this is not working.