Issue with razor views while developing custom add-on

Vote:
 

I've come across an issue while creating a custom MVC add-on. I have managed to find work-arounds to get it working but it would be useful to know if I'm doing anything wrong or missing anything.

I have created an MVC GuiPlugin but I seem to have issues with Episerver recognising referenced namespaces in the razor views. As far as I can tell, the issue seems to be that Episerver is ignoring the web.config in the root of my view folder.

  • If I use @model syntax, I get the error "the name 'model' does not exist in the current context". Workaround is to use @inherits System.Web.Mvc.WebViewPage instead
  • Using html helpers such as @Html.HiddenFor gives throws an error too, unless I explicitly reference the library at the top of the view e.g. @using System.Web.Mvc.Html

This is the web config for my Views folder https://github.com/zone/Zone.Episerver.PropertyViewer/blob/develop/src/Zone.Episerver.PropertyViewer/Views/web.config

Is there anyway to get Epi to recognise the referenced namespaces so I can write razor views in a more standard way?

#203500
Apr 25, 2019 14:24
Vote:
 

where do you put web.config file when packing addon as nuget?

#203504
Apr 25, 2019 14:39
Vote:
 

It's in my Views folder inside the zip:

  • modules\_protected\MyAddon\MyAddon.zip

Inside MyAddon.zip:

  • Views\Web.config
#203508
Apr 25, 2019 15:55
Vote:
 

I have narrowed this down a bit further - I can use @model and referenced namespaces in the views if the module is not zipped. This only seems to occur for a zipped module.

#203890
May 09, 2019 17:40
Vote:
 

Thanks David, however the problem I am getting is not that it can't find the views, as described in forum post above. My controller is finding the view, but the view errors if I use the @model syntax. If I use @inherits System.Web.Mvc.WebViewPage, the view renders correctly.

I haven't tried yet using the Geta package so I can give that a go, but I thought Razor views were supported officially.

#203901
May 10, 2019 9:59
Vote:
 

Razor views support was added at some Episerver version v10.10.x (can't remeber precisely which was it). So Geta's pacakge if I recall correctly became obsolete at that point. There were somes bugs in shell view engine resolutions that were fixed in v11.4.1.

I'm checking your repo..

try to set view engine to "razor" in module.config file:

<module viewEngine="Razor">
  ...
</module>
#203904
May 10, 2019 10:53
Vote:
 

There was a bug as valdis mentioned https://world.episerver.com/documentation/Release-Notes/ReleaseNote/?releaseNoteId=CMS-9794 

basically if you use Razor and you zip your files, then you should be using at least 11.4.1 

#203905
May 10, 2019 11:28
Vote:
 

I'm testing on the latest version of Episerver so that bug shouldn't be present. As I say, the issue is not that the view cannot be found - which is what is described in the bug fix you link to. The issue is that it doesn't recognise @model syntax, and any other referenced namespaces in the Views web.config. 

The exact same razor code works when the module is not zipped, so it seems like my Views folder web.config is not read for a zipped module.

@valdis I already have the view engine already set as you suggest:
https://github.com/zone/Zone.Episerver.PropertyViewer/blob/develop/src/Zone.Episerver.PropertyViewer/module.config

#203906
May 10, 2019 11:39
Vote:
 

can you share nuget pacakge? (maybe for now can commit to repo?)

#203907
May 10, 2019 12:42
Vote:
 

Sure, here you go: https://github.com/zone/Zone.Episerver.PropertyViewer/blob/feature/standardise-razor/src/Zone.Episerver.PropertyViewer/Packager/Zone.Episerver.PropertyViewer.1.0.0.29506.nupkg

If you install this and access the plugin (from Admin -> Property Viewer) you'll see the error. If you unzip the package to the module folder and run it again, you should see that it works.

#203913
Edited, May 10, 2019 17:27
Vote:
 

indeed. I saw Ollie, you pushed out package. did you just give up and used @inherits?

#204093
May 20, 2019 0:04
Vote:
 

I checked also zip view engine source code. nothing fancy there. so I think you should contact Episerver support for this case. they do have source code which is much nicer during debug session :)

#204094
May 20, 2019 0:06
Vote:
 

@valdis Yeah I stuck with the workaround for now. I've raised a ticket with Epi support and they confirmed that they could reproduce, so looks like it could be a bug.

#204111
May 20, 2019 10:11
Vote:
 

@Ollie, could you please try with this one?

https://www.dropbox.com/s/54p6n9kerua6amr/Zone.Episerver.PropertyViewer.zip?dl=0

I fixed the issues in your nuget file, just replace the zip in your _protected folder to test it.

The issue was that you should use:

@inherits System.Web.Mvc.WebViewPage<Zone.Episerver.PropertyViewer.Models.BlockPropertyListModel>

instead of 

@model Zone.Episerver.PropertyViewer.Models.BlockPropertyListModel

in few places you were missing the full namespace to one of your types.

#204127
May 20, 2019 13:17
Vote:
 

@Bartosz, but what is root cause for this? I've debugged (as far as I could with decompiled source) - seems like request for web.config file does not land on module zip view engine. therefore it seems like it's completely ignored. you can enter junk in web.config file and it still runs..

#204128
Edited, May 20, 2019 13:20
Vote:
 

Thanks for taking a look @bartosz.

You are correct that it works if you use `@inherits` and full namespaces - I actually mentioned this workaround in my original post:

  • If I use @model syntax, I get the error "the name 'model' does not exist in the current context". Workaround is to use @inherits System.Web.Mvc.WebViewPage instead

However, as discussed above, the @model syntax does works - but only when the package is not included in a zip file.

#204130
May 20, 2019 13:24
Vote:
 

Sorry guys, somehow I missed the workaround thing you wrote ; ) I will try to find out what's happening.

#204135
May 20, 2019 14:27
Vote:
 

When the module is zipped and served via ZipArchiveVirtualPathProvider the aspnet runtime will not discover and read the web.config from the Views folder.

That's why even if we write junk content there nothing happens. 

Since the web.config is ignored the razor engine is not fully initialized (@model not working) the <namespaces> section is missing so we have to use full namespaces etc.

The last reasonable workaround is to stop using web.config in the Views folder and add a bit more to your Web.config transformation so apart from adding a new protectedModule you would also add:

<location path="EPiServer/Zone.Episerver.PropertyViewer/Views">
  <system.web.webPages.razor>
      <host
          factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
      <pages pageBaseType="System.Web.Mvc.WebViewPage">
          <namespaces>
              <add namespace="System.Web.Mvc" />
              <add namespace="System.Web.Mvc.Ajax" />
              <add namespace="System.Web.Mvc.Html" />
              <add namespace="System.Web.Routing" />
              <add namespace="Zone.Episerver.PropertyViewer.Models" />
          </namespaces>
      </pages>
  </system.web.webPages.razor>

  <appSettings>
      <add key="webpages:Enabled" value="false" />
  </appSettings>

  <system.webServer>
      <handlers>
          <remove name="BlockViewHandler" />
          <add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode"
               type="System.Web.HttpNotFoundHandler" />
      </handlers>
  </system.webServer>
  <system.web>
      <compilation>
          <assemblies>
              <add assembly="System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
          </assemblies>
      </compilation>
  </system.web>
</location>

The only downside is that <configSections> has to be registered under <configuration>, we can't add it under our custom <location>.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
      <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
      <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
    </sectionGroup>
    <section name="episerver" type="EPiServer.Configuration.EPiServerSection, EPiServer.Configuration" restartOnExternalChanges="true" />
    <sectionGroup name="episerverModules" />
    <section name="episerver.shell" type="EPiServer.Shell.Configuration.EPiServerShellSection, EPiServer.Shell" />
    <section name="episerver.framework" type="EPiServer.Framework.Configuration.EPiServerFrameworkSection, EPiServer.Framework.AspNet" restartOnExternalChanges="true" />
    <section name="episerver.search" type="EPiServer.Search.Configuration.SearchSection, EPiServer.Search.Cms" />
    <section name="episerver.search.indexingservice" type="EPiServer.Search.IndexingService.Configuration.IndexingServiceSection, EPiServer.Search.IndexingService" />
    <section name="staticFile" type="EPiServer.Framework.Configuration.StaticFileSection, EPiServer.Framework.AspNet" allowLocation="true" />
  </configSections>

Is it an acceptable solution?

#204166
May 21, 2019 10:06
Vote:
 

Thanks @bartosz, that seems like a good solution since it sounds like it wouldn't be possible to use a View folder web.config in the standard way.

To summarize for anyone who comes across the same challenge, if you want to use razor views in a custom add-on, you can either:

  • use `@inherits` and full namespaces in your views instead of `@model`
  • leave the add-on unzipped (not too much of an issue if the total file size is small)
  • add the namespaces and related config to your root web.config as @bartosz shows above
#204170
May 21, 2019 10:58
Vote:
 

do you know the reason why web.config is being ignored?

#204171
May 21, 2019 12:21