3

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

user2047485
  • 391
  • 5
  • 20

1 Answers1

2

@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.
Alexander Christov
  • 9,625
  • 7
  • 43
  • 58
  • That library is referenced in the project already. In fact the external dll is a full Mvc website project - probably unnecessarily, but it was a quick way to ensure that all the razor syntax had intellisense etc. So it is there but obviously I am missing a trick with converting the embedded resource string to a compiled view. Do I need to set Custom Tool property? Do I need to install a Razor generator add-in? That entry already exists in my project file – user2047485 Sep 08 '15 at 08:10
  • No, you do not miss a 'trick'. It's all there, your VirtualPathProvider is responsible for ensuring the view is available when Razor chooses to compile it. You need to make sure it compiles. There is a hard way to do so: investigate the output of your views in the ASP.NET Temporary folder. Or, to make things a bit easier, add (or similar) in your web.config, then dig into it. Not very exciting, but helps. – Alexander Christov Sep 08 '15 at 08:38
  • It doesn't complain about @Html.Raw only Html.DisplayFor. I took out the DisplayFors but left Raw and that works fine. Should my VirtualPathProvider be doing more than returning new EmbeddedVirtualFile(virtualpath, stream) with the stream just GetManifestResourceStream(resourceName)? Do I need to do something with it there? – user2047485 Sep 08 '15 at 09:04
  • ok - got it. I had a using System.Web.Mvc in the view but I needed using System.Web.Mvc.Html. Doh! thanks for your time – user2047485 Sep 08 '15 at 09:13
  • :) Here's why I suggested to precompile your views. You'd have discovered the error as early as possible. Good luck! – Alexander Christov Sep 08 '15 at 11:21
  • arrrggghh! I thought I had VirtualPathProvider working but it look like my testing on bundling was affected by caching. The js files I thought were loading from an embedded resource were actually still present from an old bundle reference somehow. I can't seem to get my minified bundles to load using VPP even though the unminified ones work fine. And I have set BundleTable.VirtualPathProvider. eek. Any ideas? – user2047485 Sep 08 '15 at 15:19
  • They are web "resources" pretty much as anything else (.cshtml, .css, image files), this is why I see no reason you should experience problems with them. Just embed them as the others and they will be "served" by the VPP. – Alexander Christov Sep 08 '15 at 15:59
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/89111/discussion-between-user2047485-and-achristov). – user2047485 Sep 09 '15 at 00:02