Search code examples
c#asp.net-mvc-4razorvirtualpathprovider

MVC embedded views


I am trying to embed views in an external dll along with the css and js for them. I am mostly there. I do an Html.RenderPartial from my main project and that seems to find the embedded view and css and js no problem (using a VirtualPathProvider).

However that embedded view then calls an action (in the external dll) which returns a PartialView (also embedded). The view is found (and I have put an @inherits System.Web.Mvc.WebViewPage statement at the top to avoid errors about 'model not found in context').

However the last hurdle seems to be an error about "...WebViewPage does not contain a definition for 'DisplayFor'....." because I am using @Html.DisplayFor(.....

Can anyone tell me what I need to do for this final bit of the puzzle to work? I have copied the web.config from the Views folder into the bin folder where my dlls are (as seemed to be impled by other posts) but that hasn't helped.

thanks very much

PS When the build action for the views was set to Copy To Output Directory and I used a ViewEngine to point to the bin/views directory it all worked fine. It's only now that I have changed to Embedded Ressource


Solution

  • @Html.DisplayFor(...) is an extension method with the following signature:

    public static MvcHtmlString DisplayFor<TModel, TValue>(
        this HtmlHelper<TModel> html,
        Expression<Func<TModel, TValue>> expression,
        string templateName
    )
    

    It resides in System.Web.Mvc.Html (System.Web.Mvc.dll) that needs to be referenced, so that the view compiles correctly. How you'd reference it is another question, but you may have it in other views rendered thru the default VPP, or you may do the following:

    • If you want to make sure it is available in order to try to diagnose why it is not loaded at runtime, you may wish to precompile your views. Just add the following to your project file:

      <Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
          <AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
      </Target>
      

    This will reveal any errors you may have in your views compiling them upon build rather then run-time.

    • If, however, you still cannot reference the assembly at runtime, then you may need to add it with BuildManager.AddReferencedAssembly. Here I am not going to copy/paste contents of the above link, you may read it and read additional info as well. Beware, however, referencing it by using a helper in another view, may be a safer solution, since if it is already referenced, the above method notices this fact and reports an error.