Razor Class Library (RCL) _ViewImports ignored when site runs
Asked Answered
E

1

3

I've created a Razor Class Library (RCL) to create a 'common UI' for several sites following the pattern from this article. But I'm having a problem with the _ViewImports.cshtml.

In my RCL, I have a _TemplateLayout.cshtml. It uses some classes from a library named BTR.Camelot.Infrastructure. So in the _ViewImports.cshtml, I have:

@using BTR.Camelot.Infrastructure.Serialization

So that the RCL will compile. Without that, it does not compile.

When I run my project that references the RCL and uses its template, I get the following error:

The name 'JavascriptSerializer' does not exist in the current context Sys.CultureInfo.CurrentCulture = Sys.CultureInfo._parse(@Html.Raw( JavascriptSerializer.MicrosoftAjaxCultureInfo ));

JavascriptSerializer is in my BTR.Camelot.Infrastructure.Serialization namespace. My guess is that:

  1. The _ViewImports.cshtml is used in the RCL to make sure it can compile.
  2. The _ViewImports.cshtml from the site takes precedence over the _ViewImports.cshtml from the RCL and the RCL version is completely ignored.

Is there a way to make the _ViewImports.cshtml files 'merge'? This question seems to acknowledge that this problem exists but just accepted that you should remove the sites _ViewImports.cshtml. I'm hoping there is a work around.

My Project Structure

RootFolder
+-- SiteTemplates
|   +-- Evolution
|   |   +-- Pages
|   |   |   +-- _ViewImports.cshtml
|   |   +-- Evolution.csproj
|
+-- Websites
|   +-- Personal
|   |   +-- RTC
|   |   |   +-- Pages
|   |   |   |   +-- Shared
|   |   |   |   |   +-- _TemplateLayout.cshtml
|   |   |   |   +-- _ViewImports.cshtml
|   |   |   +-- RTC.csproj
|
+-- Infrastructure
|   +-- Infrastructure.csproj

RTC (main site) references Infrastructure.csproj and Evolution.csproj (RCL).

Evolution.csproj references Infrastructure.csproj.

Evolution/Pages/_ViewImports.cshtml

@using BTR.Camelot.Infrastructure.Configuration
@using BTR.Camelot.Infrastructure.Serialization
@using BTR.Camelot.SiteTemplates.Evolution.Resources

@using Microsoft.AspNetCore.Mvc.Localization
@using Microsoft.Extensions.Options

@namespace BTR.Camelot.SiteTemplates.Evolution.Pages

RTC/Pages/_ViewImports.cshtml

@namespace BTR.Camelot.Websites.Personal.RTC.Pages

@using BTR.Camelot.Websites.Personal.RTC.Models
@using BTR.Camelot.Infrastructure.Configuration
@using BTR.Camelot.Core.Extensions.LINQ
@* Not using/needing Serialization here, but RCL Layout file does.  See comment in RCL _ViewImports.cshtml *@
@using BTR.Camelot.Infrastructure.Serialization

@using Microsoft.AspNetCore.Mvc.Localization
@using Microsoft.Extensions.Options

And if I remove or comment out @using BTR.Camelot.Infrastructure.Serialization in the RTC project, then I receive the exception.

Extra answered 4/1, 2021 at 4:29 Comment(9)
Did you reference the incorrect package?Pry
Not sure I understand the question.Extra
In the _ViewImports.cshtml of which project do you have the "@using BTR.Camelot.Infrastructure.Serialization"? (I'm guessing the RCL?)Mindi
Yes, the RCL, I stated that above. But I need it also in the application site for things to work. Reading the documentation learn.microsoft.com/en-us/aspnet/core/mvc/views/…, it looks like it should allow usings from various _ViewStart and merge them.Extra
Yes you are correct it should merge them, ignoring only duplicate imports. I noticed in your last comment you said in your "_ViewStart", I believe you meant _ViewImports.Mindi
Can you show your _ViewImports in both projects, as well as your solution structure?Mindi
@Lord-Link I updated my question to have my structure. I see you and I are having some comments on https://mcmap.net/q/1629518/-net-core-2-1-reusing-_layout-throughout-various-projects as well. But as you can see in this question, it doesn't seem to be working as documented by Microsoft.Extra
@Extra Looking over your code it doesn't seem wrong and from my understanding you shouldn't need to include the using BTR.Camelot.Infrastructure.Serialization in your RTC project. I'm not too sure why it's giving you that error when you remove it... If you leave the using in the RTC project does the solution work? If not what's the error message?Mindi
It works. It just seems wrong that a consumer of a RCL (and a layout file inside the RCL) has to know all the @using statements to use to make the RCL function/compile.Extra
D
1

I just hit this problem of the application's _ViewImports being the only one used, even ehen there's one in the RCL - for me they did not auto-merge. What I have as a workaround is quite simple, but requires a little bit of setup work when the RCL is used in an application.

In my RCL, I set up my _ViewImports.cshtml as required to compile the RCL. For me this includes setup for Syncfusion Tag Helpers. I then immediately copy the _ViewImports.cshtml to a new file, the name is unimportant, so let's say '_RCL_ViewImports.cshtml'.

In the Application side, you can either remove the '_ViewImports.cshtml' in which case the RCL's '_ViewImports.cshtml' will be used, or you can add a Partial to your application's _ViewImports.cshtml. The resultant file might look like this:

@using ExampleApp
@namespace ExampleApp.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@await Html.PartialAsync("_RCL_ViewImports")

I haven't tried yet, but I would imagine that if an application used multiple RCL's and each RCL had a differently named _RCL_ViewImports.cshtml, then you could include the imports from all of them.

I'm not sure why an auto merge is not occurring if indeed it's supposed to happen at all, but I'm happy with this workaround.

Mark

Dalmatia answered 2/6, 2023 at 10:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.