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 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
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 use the SDK ending with ".Web".
So, I updated the ASP.NET Core Class Library csproj file to the same Project Sdk value as the ASP.NET Core 3.1 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