locked
Class Library Tag Helper for Partial Pages not working in ASP.NET Core Razor Pages application RRS feed

  • Question

  • User-580799299 posted

    As part of my work on an ASP.NET Core 3.1 Razor Pages web application, I created several custom Tag Helpers. Once I had all of these working the way I wanted and expected (as part of the ASP.NET Core 3.1 application), I moved the Tag Helpers to a Razor Class Library (.NET Standard 2.1), so I could use the custom Tag Helpers in other applications.

    That is where I ran into a problem with a Tag Helper to render a Partial Page using the PartialTagHelper class:

    TypeLoadException: Could not load type 'Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.IViewBufferScope' from assembly 'Microsoft.AspNetCore.Mvc.ViewFeatures, Version=3.1.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'.

    The constructor for the PartialTagHelper class requires the IViewBufferScope parameter noted in this error and is passed into the custom Tag Helper code via Dependency Injection.

    In the ASP.NET Core 3.1 Razor Page, the custom Tag Helper code requires a 'using' reference to the Microsoft.AspNetCore.Mvc.ViewFeatures.Buffers namespace.

    In the Razor Class Library, the custom Tag Helper code requires a 'using' reference to the Microsoft.AspNetCore.Mvc.ViewFeatures.Internal namespace. 

    I also tried using .NET Standard 2.0 and 2.1 as well as .NET Core 3.1 Class Libraries.  In all of these situations, the Class Library required references to Microsoft.AspNetCore.Mvc.ViewFeatures version 2.2.0 and Microsoft.AspNetCore.Razor version 2.2.0 in order to compile.

    So, the error sounds like ASP.NET Core 3.1 Razor Page is injecting the 3.1.3 Microsoft.AspNetCore.Mvc.ViewFeatures assembly and this does not contain the IViewBufferScope parameter from the correct assembly.

    Is there a way to resolve this?

    Thanks

    Sunday, May 17, 2020 5:41 PM

Answers

  • User-580799299 posted

    A little over a week ago (on 5/20/2020), I found out how to create a package that would work for the ASP.NET Core 3.1 Razor pages, but had a different package that would work for lower version levels (for example, a .NET Framework 4.8 Razor Pages application).  Let me first explain how I initially got things to work and then I will explain how I now have a single package that I can use for either the .NET 4.8 Razor Pages or the .NET Core 3.1 Razor Pages.

    Since I was originally able to get the TagHelper for Partial Pages to work as part of my ASP.NET Core 3.1 Razor Pages application, I compared the csproj file from that web application to my ASP.NET Core 3.1 Class Library csproj file.

    That is when I noticed the ASP.NET Core 3.1 Razor Pages csproj file started with: 

    <Project Sdk="Microsoft.NET.Sdk.Web>

    But the various Class Library projects did not end with ".Web".

    So, I updated the ASP.NET Core Class Library csproj file to the same Project Sdk value as the ASP.NET Core Razor Pages application.

    When I saved the csproj file, it automatically updated the Output Type (on Project Properties Application tab) to Console Application.  I changed this to Class Library and I am now able to use the Partial Page Tag Helper without any errors, so my problem is partially solved.

    Here is my csproj file for the Class Library:

    <Project Sdk="Microsoft.NET.Sdk.Web">
     
        <PropertyGroup>
            <TargetFramework>netcoreapp3.1</TargetFramework>
            <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
            <IsPackable>true</IsPackable>
            <Version>1.0.5</Version>
            <OutputType>Library</OutputType>
        </PropertyGroup>
     
    </Project>
    

    This reason I say partially solved my problem is that further changes are required to have a single package for the ASP.NET Core 3.1 Razor Pages as well as lower version Razor Pages web applications like .NET Framework 4.8 Razor Pages or even .NET Core 2.2 Razor Pages.  A couple things are required.

    First, replace the TargetFramework entry in the PropertyGroup to TargetFrameworks and add netstandard2.0:

    <TargetFrameworks>netcoreapp3.1;netstandard2.0</TargetFrameworks>

    Next, add a conditional ItemGroup for the PackageReferences needed by the .NET Standard 2.0 TFM (Target Framework):

        <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
            <PackageReference Include="Microsoft.AspNetCore.Mvc.TagHelpers" Version="2.2.0" />
            <PackageReference Include="Microsoft.AspNetCore.Mvc.ViewFeatures" Version="2.2.0" />
            <PackageReference Include="Microsoft.AspNetCore.Razor" Version="2.2.0" />
        </ItemGroup>
    

    Finally, all of the Class Library code is exactly the same to support ASP.NET Core 3.1 and .NET Standard 2.0, except one using statement in the custom Tag Helper for Partial pages, so add a conditional compile check as follows:

    #if NETCOREAPP3_1
    using Microsoft.AspNetCore.Mvc.ViewFeatures.Buffers;
    #else
    using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
    #endif
    
    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, May 21, 2020 7:44 AM

All replies

  • User-474980206 posted

    while you could add the nuget abstraction projects, the easiest fix is to update the target framework in the project file.

    <PropertyGroup>
        <TargetFramework>netcoreapp3.0</TargetFramework>
    </PropertyGroup>
    

    Monday, May 18, 2020 3:21 PM
  • User-580799299 posted

    Thanks for your response Bruce.  I had tried several ways of setting my Class Library up, including manually editing the csproj file, updating the version in the Property pages and creating a new project from scratch.

    In each of these cases, I had to add a references to Microsoft.AspNetCore.Mvc.TagHelpers, Microsoft.AspNetCore.Mvc.ViewFeatures and Microsoft.AspNetCore.Razor ... All of these were Version="2.2.0"

    These all failed with the same problem reported in my original post.

    Thursday, May 21, 2020 7:21 AM
  • User-580799299 posted

    A little over a week ago (on 5/20/2020), I found out how to create a package that would work for the ASP.NET Core 3.1 Razor pages, but had a different package that would work for lower version levels (for example, a .NET Framework 4.8 Razor Pages application).  Let me first explain how I initially got things to work and then I will explain how I now have a single package that I can use for either the .NET 4.8 Razor Pages or the .NET Core 3.1 Razor Pages.

    Since I was originally able to get the TagHelper for Partial Pages to work as part of my ASP.NET Core 3.1 Razor Pages application, I compared the csproj file from that web application to my ASP.NET Core 3.1 Class Library csproj file.

    That is when I noticed the ASP.NET Core 3.1 Razor Pages csproj file started with: 

    <Project Sdk="Microsoft.NET.Sdk.Web>

    But the various Class Library projects did not end with ".Web".

    So, I updated the ASP.NET Core Class Library csproj file to the same Project Sdk value as the ASP.NET Core Razor Pages application.

    When I saved the csproj file, it automatically updated the Output Type (on Project Properties Application tab) to Console Application.  I changed this to Class Library and I am now able to use the Partial Page Tag Helper without any errors, so my problem is partially solved.

    Here is my csproj file for the Class Library:

    <Project Sdk="Microsoft.NET.Sdk.Web">
     
        <PropertyGroup>
            <TargetFramework>netcoreapp3.1</TargetFramework>
            <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
            <IsPackable>true</IsPackable>
            <Version>1.0.5</Version>
            <OutputType>Library</OutputType>
        </PropertyGroup>
     
    </Project>
    

    This reason I say partially solved my problem is that further changes are required to have a single package for the ASP.NET Core 3.1 Razor Pages as well as lower version Razor Pages web applications like .NET Framework 4.8 Razor Pages or even .NET Core 2.2 Razor Pages.  A couple things are required.

    First, replace the TargetFramework entry in the PropertyGroup to TargetFrameworks and add netstandard2.0:

    <TargetFrameworks>netcoreapp3.1;netstandard2.0</TargetFrameworks>

    Next, add a conditional ItemGroup for the PackageReferences needed by the .NET Standard 2.0 TFM (Target Framework):

        <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
            <PackageReference Include="Microsoft.AspNetCore.Mvc.TagHelpers" Version="2.2.0" />
            <PackageReference Include="Microsoft.AspNetCore.Mvc.ViewFeatures" Version="2.2.0" />
            <PackageReference Include="Microsoft.AspNetCore.Razor" Version="2.2.0" />
        </ItemGroup>
    

    Finally, all of the Class Library code is exactly the same to support ASP.NET Core 3.1 and .NET Standard 2.0, except one using statement in the custom Tag Helper for Partial pages, so add a conditional compile check as follows:

    #if NETCOREAPP3_1
    using Microsoft.AspNetCore.Mvc.ViewFeatures.Buffers;
    #else
    using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
    #endif
    
    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, May 21, 2020 7:44 AM