TypeLoadException Could not load type 'WebConfigurationManager' when calling .Net Framework Library via Web API Core app - c#

I have a Web API application created using .Net Core 2.1. A controller from within this web application calls a Business Layer Class library that I also developed using .Net Core 2.1. So far so good...
The .Net Core Business Class Library references a commonly used .Net Framework 4.6.1 Class Library that we have also developed. This library is primarily used to communicate with Azure service bus queues.
As a result this commonly used .Net Framework Class Library in turn references and makes use of the Microsoft .Net Framework Assembly, Microsoft.ServiceBus as shown in the line of code below.
MessagingFactory messagingFactory = MessagingFactory.CreateFromConnectionString(configValue);
As you can see the line of code above that is within our commonly used .Net Framework Class Library passes a string value (i.e. configValue) to a static method that exists within the Microsoft.ServiceBus assembly.
However, whenever the line of code above executes I get the following Error:
An unhandled exception occurred while processing the request.
TypeLoadException: Could not load type
'System.Web.Configuration.WebConfigurationManager' from assembly
'System.Web, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a'.
Out of interest I added in the following line of code which I get the same error:
string configValue = WebConfigurationManager.AppSettings["connectionString"];
Clearly, the issue is that the System.Web .Net Framework assembly isn't loaded.
However, given that the web application is .Net Core then how can I make this web application load the underlying .Net Framework assembly that the commonly used library requires?
Solutions Considered - (Unsuitable)
I had a similar issue before which was easily solved by installing the necessary NuGet package but on this occasion I have not been able to find such a package.
Our team has another Web API application in .Net Framework which calls this commonly used class library without issue however this is not an option and we need to keep the current Web API application based on .Net Core.
I also considered having the commonly used library re-written as a .Net Standard 2.0 Class Library but this given the size of the library this would not be a realistic approach and it won't necessarily address the underlying issue.
Other Possible Solutions
Load a Web.config from within the .Net Core Web API application that contains a configSections section referencing the assembly System.Web. I tried this but it didn't work which I'm sure if I just didn't apply all steps necessary. Is this possible and if so any suggestions?
Is there an alternative way to load the .Net Framework assembly from within the .Net Core Web API?
Sacrifice using the commonly used library and find an alternative (sample) code base that provides similar functionality (i.e. make use of Microsoft.ServiceBus to work with our Azure queues) but that is either .Net Core or .Net Standard based. But similar to the .Net Standard solution above I am unsure how much functionality would need replicated and also unsure of a starting point. Thoughts?
Thanks!

I had the same issue and after investigating i found that my azure function app run time version is 2.0 ~ and according to documentation version 2 is .NET Core 2 and function app version 1.0 ~ is .NET Framework 4.7 . and my visual studio function app project have .NET Framework 4.6.1 . So, I just had to change my function app version to ~ 1.0 .
In a Nutshell
If you have visual studio function app in .NET Core 2.0 then only use function app version 2.0
If you have visual studio function app in .NET Framework 4.7 then only use function app version 1.0

Related

Microsoft.Data.SqlClient is not supported on this platform with plugins architecture on .NET Core Web API

I have an app that is a .NET Core 5 Web API "container".
I load dynamically multiples projets "Web API" as DLL.
Unfortunately, when a project is using EF to request a database, I got Microsoft.Data.SqlClient is not supported on this platform error.
By adding Microsoft.Data.SqlClient as a nuget package on my web api container, it works but what I am not understanding is why my library, which should contains all the dll that is required by itself, cannot make a query into the database.
I have specified in the library csproj this settings :
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
and in the output folder I can see Microsoft.Data.SqlClient.dll
I run the project on my laptop, so no Azure involved.
Thanks for yor help !
Edit 1 :
I have seen this : https://github.com/dotnet/SqlClient/wiki/Frequently-Asked-Questions#11-why-do-i-get-a-platformnotsupported-exception-when-my-application-hits-a-sqlclient-method
I wondering how I can indicate in my class library .NET 5 that this class lib will be used under a .NET 5 Web Api as it seems that despite targeting .NET 5 in both project, is not enough to get the appropriate dll...

EntityFramwork compatibility with .net framework 4.7.2 projects and .net standard 2.0 project

I have shared project that use entity framework 6.4 and it represents data access layer in other projects with .net framework 4.7.2.
I also have created an azure function version 2 project. The framework is .net standard 2.0 which supports .net core 2, as it is needed for azure functions.
The problem happens when I want to use that shared entity framework project in azure function. Since EntityFramework 6.4 is not supported on .net standard 2.0
I am looking for a solution to upgrade or downgrade or even framework change to use that shared entity framework project in azure function and all other projects.
Entity Framework 6.4 is compatible with netstandard 2.1, but not 2.0, meaning it requires dotnet core 3.0 at minimum.
But if you can upgrade your azure function project to target core 3.0, you can enable multi-targeting in your data layer project.
Open the csproj file and replace :
<TargetFramework>netstandard2.0</TargetFramework>
by
<TargetFrameworks>netstandard2.1;net472</TargetFrameworks>
Note the change from TargetFramework to TargetFrameworks, this is important!
This will enable the project to be referenced by projects targeting the full framework (4.7.2 and above) as well as anything supported by net standard 2.1.
If you use v1 version of Azure Functions there are less compatibility issues, EF for instance is supported but you might still run into issues with other dependencies.
I have had great success in the past by creating V2 functions that operate as a "front end" that post messages to Event Hubs or a Service bus Queue. Then use a continuous web job to process these queued messages in .net framework code, which I now refer to as the "legacy" portion of my solution.
Another option is to use a REST API that runs in .net fx, this will keep your functions lightweight as they only need to call endpoints in the API

Using .NET Standard library with Windows Compatibility Pack in .NET Framework

I'm working on migrating a large code base of libraries in a direction to eventually support .NET Core. Currently, everything is based on .NET Framework. I have a set of library projects which are consumed by several web applications.
The plan is to convert the library projects over to .NET Standard 2.0 so that they can be consumed by both .NET Framework (version 4.7.1) based websites and by new .NET Core (version 2.0) websites. I've done some test solutions which proved that this can be done.
To convert the first library over to .NET Standard I had to leverage the Windows Compatibility Pack for some of the features that are not part of .NET Standard. Some features such as SqlClient and some System.Drawing tools had to be imported into the library. All of this worked but an issue turned up when trying to bring my library into code which was still targeting .NET Framework.
Even though the namespaces were the same, the consuming code could not see the objects (such as Image or SqlConnection) unless I added the same Windows Compatibility Pack libraries into the consuming project. If anything, I would have expected this to cause issues as I now have two identical classes (same namespace and object name) in different assemblies. Fortunately, it is working. At least the unit tests are still passing.
Is this the way the Windows Compatibility Pack libraries are supposed to work? I had hoped that they would provide the functionality in the .NET Standard or .NET Core code but allow the .NET Framework to still use its own implementation.
The compatibility package references a few of the assemblies that were brought back to increase the compatibility of .NET Core with .NET Framework.
The way the package works is that there is a meta-package (the one that you reference) and it has references to individual packages that actually contain the implementation. Those individual packages have different assets depending on the target framework.
Take for example System.IO.Ports. That package contains the following assets (and a few more things that are not directly relevant to this):
net461
netstandard2.0
The netstandard2.0 asset contains the code that implements the System.IO.Ports functionality. You will use this if you are building a .NET Core application.
The net461 asset type-forwards the types exposed by the System.IO.Ports namespace to the assemblies you will find in the .NET Framework installation. You will use these if you are building a .NET Framework application (like a console application of web site).
This means that when you are consuming your library on .NET Core, you are using the implementation that was ported and made to work on .NET Core.
When you are using your library on .NET Framework you will use the implementation that is part of .NET Framework.

Log4Net with .net core 2 and framework Wrapper

I'm prototyping a .net core 2 web application. I've been asked to use Log4Net for handling our logging, but I want to put it in a .net framework 4.6.1 wrapper project as to allow for changing out the internal logging systems without having to update all of the method calls throughout the site.
Everything that I've found so far is for doing one or the other. Wrapping the log4net in 4.6.1 or doing a direct reference to the .net core.
So far, my 2 main exceptions are "FileNotFoundException" for when I use it as a direct reference, or when I do the PackageReference in the Framework proejct files I get a "Logging is not compatible with netcoreapp2.0. Logging is framework 4.6.1.
First, I would recommend making your wrapper using .NET standard 1.3 as this is the currently .NET core version supported by log4net, plus, this would allow you to reference this wrapper in .NET core and .NET framework 4.6 and up.
Second, see: https://stackify.com/making-log4net-net-core-work/ for some more info on getting log4net working with .NET core.

How do I reference a .NET Framework project in a .NET Core project?

I'd really like to start using .NET Core and slowly migrate applications and libraries to it. However, I can't realistically upgrade my entire code base to use .NET Core and then go through the process of testing and deploying a plethora of applications in production.
As an example, if I create a new .NET Core application and try to reference one of my .NET Framework projects I get the following:
The following projects are not supported as references: -
Foobar.NetFramework has target frameworks that are incompatible with
targets in current project Foobar.NetCore.
Foobar.NetCore: .NETCoreApp,Version=v1.0
Foobar.NetFramework: .NETFramework,Version=v4.5
Is it possible to create a new .NET Core application and reference my existing .NET Framework libraries? If so, what's the process for doing that? I've spent hours going through Microsoft's documentation and searching their issues on GitHub, but I can't find anything official on how to achieve this or what their long-term vision is for this process.
Old question, but with the release of .NetStandard 2.0 and .netcore 2.0 and vs2017.3, the game has changed.
You can use the Full .NET Framework (TFM) with .NetCore 2.0, but how?
In Visual Studio 2017.3, you can reference the Full .NET Framework (any version) directly from within a .NetCore2 project.
You can build the .NetStandard2 class library and reference your TFM. Then reference your .NetStandard2 library from your .NetCore2 project.
For example, referencing json.net net45 from .NetStandard2.
Browse to the folder and select version net45 (not netstandard1.3)
See the dependency in the image below, no yellow warning as you see.
Even if a Nuget library is not ready to be ported to .Netstandard 2, you can use any API in the library that is compliant to net461.
Quoting for the .NET Core 2/Standard 2.0 announcement with links:
.NET Core 2.0 is able to freely reference libraries that have been built for .NET Framework up to version 4.6.1
However, some libraries may fail at run time if they try to use API methods that aren't available on .NET Core
Reference: .NET Core App target .NET framework 4.5.2 on Linux
A need to use third-party .NET libraries or NuGet packages not available for .NET Core
So only in cases where the libraries or NuGet packages use technologies that aren't available in .NET Standard/.NET Core, you need to use the .NET Framework.
Reference: Choosing between .NET Core and .NET Framework for server apps
You can now reference .NET Framework libraries from .NET Standard libraries using Visual Studio 2017 15.3. This feature helps you migrate .NET Framework code to .NET Standard or .NET Core over time (start with binaries and then move to source). It is also useful in the case that the source code is no longer accessible or is lost for a .NET Framework library, enabling it to be still be used in new scenarios.
Reference: Announcing .NET Core 2.0
Yes, we are currently attempting the same thing. The trick is to make sure that you are supporting the same .NET frameworks. Inside your project.json file, make sure the framework matches the framework of the project you wish to include. For example:
"frameworks": {
"net46": { --This line here <<<<
"dependencies": {
"DomainModel": {
"target": "project"
},
"Models": {
"target": "project"
}
}
}
},
FYI: You might need to change the framework of your .NET Core or your older projects to achieve this. .NET Core can be changed just by editing the project.json file as seen above. You can so the same in .NET projects by right clicking the project and opening properties. Change the framework level there.
Once you have matched the two project frameworks then you should be able to include them. Good Luck!
We delayed migrations as long as could as it seemed daunting as first. But we got an insistent client who wanted to migrate ASAP.
So we migrated their Fintech Web App developed on .NET Framework 4.8 Web Forms to .NET 6 Razor Page. Our team scoured though hundreds of online resources & spoke to Microsoft Tech Support before we started the project. Hope the high-level walkthrough of our journey help you plan your migrations.
Our .NET Framework Website consisted of 1 .NET Web Forms project and 12 Class Libraries.
Here is how we did it.
Refactored the .NET Framework 4.8 Web Forms code
We ensured that the Web Forms code behind did not have a single line of service or business logic code. When we did find some business logic code in the web forms code behind, we refactored it, by moving it to the class libraries.
Created new .NET Standard projects
We created a new .Standard 2.0 Class library project for every .NET Framework 4.8 Class Library. If the original project was called "FintechProjectName.StockMarketClient", we named the .NET standard project "FintechProjectName.StockMarketClient.Standard".
Copied all files from .NET framework to .NET standard
We copied all the class files from .NET framework to .NET standard projects. We then removed all the .NET framework class libraries from the solution and added references to the new class libraries. All projects compiled on the 1st try itself and all our test cases too passed with minor changes.
Create new .NET 6 Web App Project
We created a new .NET 6 Web App Project. We had to entirely redo the front-end as there is no direct path for migrating Web Forms to Razor Pages. This was the only project which took us about 1 month to migrate.
Reference .NET standard class libraries in the new .NET 6 website
We copied all the .NET Standard libraries to this new solution containing the Razor Pages web site. Added the references and got it to work.
Move from .NET Standard to .NET 6 class libraries
Once the new website was up and running, with all test cases passed, we did the last step in the process which was the simplest. Created .NET 6 class library projects for each of the .NET standard libraries and named the projects appropriately. Copied all class files from .NET standard projects to their corresponding .NET 6 projects. Then we removed the .NET Standard libraries and added references to the new class libraries.
Overall project timelines were about a month and a half, most of it spend on Razor Pages implementation using the same html design.
Note:
If you are using any 3rd party library which does not have a .NET standard or .NET 5 version, then you are out of luck. You will need to find a replacement nuget package and recode your application to use this new library.
In my case with .net6 referencing framework 4.8 library ( both winforms), the trick seems to be to add the reference to the framework dll as a shared reference.

Categories

Resources