Re-Usable Core Display/Editor Template Libary + Override Views

Nov 17, 2011 at 9:42 AM
Edited Nov 17, 2011 at 9:43 AM

Hi, i've been playing around with using embedded views and trying to modify the inbuilt view engine but i stumbled across this project and it looks quite promising. I was wondering if i could do the following:

  1. Share Display/Editor Templates across projects. It would be quite handy if you could create a core library of Display/Editor Templates which can then be referenced from another project and used with that.
  2. Override the views in any of the referenced libraries which use Razor Generated views from within the consuming web application.

I'd be greatful if someone could let me know if this can be done or if it can be adjusted simply to allow this.

Thanks

Coordinator
Nov 17, 2011 at 4:42 PM

1) I haven't tried this as yet, but the person at http://razorgenerator.codeplex.com/discussions/278608 seems to have had some success with creating precompiled editor templates.

2) We don't have support for the second one as yet. Tweaking the order in which ViewEngines are registered would determine where the view gets served from, but it doesn't work on a per view basis. A related change we were considering is to have our view engine serve files from disk if they are newer than the compiled assembly so you could change views and view them without having to rebuild your project.

Nov 17, 2011 at 7:55 PM

Hi thanks for your response. I will test 1 tomorrow and report back on my findings. As for number 2 i have tried playing with the source and modifying the PreCompiledMvcEngine but to be honest i don't fully understand what's going on. Say my application has the following structure:

MyApp.Web (ASP.NET MVC Web Application)
  Views
    Home
      Index.cshtml

MyApp (Class Library)
   Views
     Home
       Index.cs.html (Razor Generated)

Surely it would be quite trivual to say if the HttpContext.Current.Server.MapPath("~/Views/Home/Index.cshtml") file doesn't exist then use the Razor Generated view engine else use the inbuilt view engine. The only problem is i'm assuming it's trivual to someone who knows what they're doing if that makes sense lol.

I'd appreciate it if you could show me how this can be done or atleast point me in the right direction.

Thanks

Nov 18, 2011 at 8:21 AM
Edited Nov 21, 2011 at 1:01 PM

I think i have managed to come up with a solution for number 2. I have simply modified the CreatePartialView and CreateView methods to be:

protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
{
    Type type;

    if (File.Exists(HttpContext.Current.Server.MapPath(partialPath)))
        return new RazorView(controllerContext, partialPath, null, false, base.FileExtensions);
    else if (_mappings.TryGetValue(partialPath, out type))
        return new PrecompiledMvcView(partialPath, type, false, base.FileExtensions);

    return null;
}

protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
{
    Type type;

    if (File.Exists(HttpContext.Current.Server.MapPath(viewPath)))
        return new RazorView(controllerContext, viewPath, masterPath, true, base.FileExtensions);
    else if (_mappings.TryGetValue(viewPath, out type))
        return new PrecompiledMvcView(viewPath, type, true, base.FileExtensions);

    return null;
}

And changed the Exists method to also also check if the file or mapping exists. So far it works for me. Please let me know if you think there's anything i have missed. Please also note that your suggestion about returning the file from disk if they are newer than the assembly version doesn't really work for me. Imagine you have an inbuilt module/area in a content management systems core library. Now for a particular site you wish to change the design for a view then you override it within the web application. If the module in the core library changes and the web application upgrades to the latest core library then it will override the overridden view. Hope that makes sense.

I have also been able to successfully test Editor and Display templates aswell.

Thanks for your help.

Coordinator
Nov 18, 2011 at 4:10 PM

This does work but as I said before if you tweak the order in which ViewEngines are registered you can get something similar. If you look at samples\MvcSample\HomeController.cs, we have an action which essentially does what you're trying to achieve - let the default Mvc view engine hijack urls that are present on disk