简体   繁体   中英

ASP.NET Web Application Using .NET Standard Library

I'm just getting started with .NET Standard, and I'm trying to grasp best practices in this new scenario. I've transitioned a few of my key libraries to .NET Standard 2.0. When I make a new Web application (ASP.NET 4.6.1, 4.6.2, or 4.7) project, add my new libraries as references, and then build, I get lots of warnings. None of these warnings are shown if the library targets .NET Standard 1.4 or earlier, but I need .NET Standard 2.0. This is a portion of those warnings:

Consider app.config remapping of assembly "System.Runtime.Serialization.Xml, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" from Version "4.0.10.0" [C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Runtime.Serialization.Xml.dll] to Version "4.1.3.0" [C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\\net461\ref\System.Runtime.Serialization.Xml.dll] to solve conflict and get rid of warning.
... [About 50 similar lines] ...
Consider app.config remapping of assembly "System.Runtime.InteropServices.RuntimeInformation, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" from Version "0.0.0.0" [] to Version "4.0.2.0" [C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\\net461\ref\System.Runtime.InteropServices.RuntimeInformation.dll] to solve conflict and get rid of warning.

The very last warning I get is this:

C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets(1987,5): warning MSB3247: Found conflicts between different versions of the same dependent assembly. In Visual Studio, double-click this warning (or select it and press Enter) to fix the conflicts; otherwise, add the following binding redirects to the "runtime" node in the application configuration file:
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"><dependentAssembly><assemblyIdentity name="System.Runtime.Serialization.Xml" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" /><bindingRedirect oldVersion="0.0.0.0-4.1.3.0" newVersion="4.1.3.0" /></dependentAssembly></assemblyBinding>
... [About 50 similar lines] ...
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"><dependentAssembly><assemblyIdentity name="System.Runtime.InteropServices.RuntimeInformation" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" /><bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" /></dependentAssembly></assemblyBinding>

If I double-click that warning, it adds the appropriate binding redirects to my Web.config file. But I'm wondering the following:

  1. Am I doing something wrong? It's hard for me to believe that adding all these binding redirects is expected for a .NET Framework 4.6.1 application to reference a .NET Standard library.

  2. Why is this all this binding redirection necessary? Why can't my Web application just use the same assemblies the .NET Standard library is using without binding redirects? Why does my Web application default to using old versions of these assemblies?

  3. Possibly related to this issue is that my application can start (with or without binding redirects) but quickly fails when I try to use SqlClient: "Could not load file or assembly 'System.Data.SqlClient, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified." This exception is thrown within a library that is using System.Data.SqlClient 4.4. I tried to add this binding redirect, but it hasn't helped: <dependentAssembly><assemblyIdentity name="System.Data.SqlClient" publicKeyToken="B03F5F7F11D50A3A" culture="neutral"/><bindingRedirect oldVersion="0.0.0.0-4.4.0.0" newVersion="4.4.0.0"/></dependentAssembly> I later discovered that if I intentionally add the System.Data.SqlClient NuGet package to the ASP.NET project and add a binding redirect to the ASP.NET project's Web.config, the SQL operation can execute. (The binding redirect looks like this: <dependentAssembly><assemblyIdentity name="System.Data.SqlClient" publicKeyToken="B03F5F7F11D50A3A" culture="neutral"/><bindingRedirect oldVersion="0.0.0.0-4.4.0.0" newVersion="4.2.0.0"/></dependentAssembly> Even though I added the 4.4 NuGet package, when I build, 4.2 is output to the bin directory. I don't know why it would do that, but if it would output 4.4, I don't think the binding redirect would be necessary.)

Thanks to a comment by Lex Li, I was led to this page: https://github.com/dotnet/standard/issues/481

I want to extract some portions that were especially useful in answering my sub-questions:

  1. The following statement answered my sub-question #1, regarding the correctness of adding tons of binding redirects.

Web applications and web sites don't support automatic binding redirect generation. In order to resolve binding conflicts, you need to double click the warning in the error list and Visual Studio will add them to your web.config file.

  1. The following statement answered my sub-question #2, regarding why all of this was necessary and why it seems so unfinished:

Believe me, no one on my team is keen on on the way the net461 support story has unfolded. In a sense, what you're asking has already been implemented: .NET Framework 4.7.1 will ship with full built-in support of .NET Standard 2.0. The challenge is that (1) it hasn't been shipped yet and (2) many of our customers will not be able to upgrade immediately because the target environment is outside their control. The option was to support it the best we can or can it altogether. Yes, this unfortunately requires jumping through hoops but at least there is something app developers can do. If you fully control the environment, by all means, jump to .NET Framework 4.7.1.

  1. The following statement answered my sub-question #3, regarding why assemblies couldn't be found.

The only supported mode for SDK-style projects (.NET Core/.NET Standard) is PackageReference . This means that a .NET Framework project referencing a .NET Standard project ends up crossing the streams between two different NuGet models. When the .NET Standard project references NuGet packages that the .NET Framework project doesn't reference, the application ends up missing all binaries coming from those packages.

Based on this table of supported platforms , if you are on .NET 4.6, you can only consume libraries built on (up to) .NET Standard 1.3. You cannot use libraries built on .NET Standard 2.0 unless you move up to .NET 4.6.1 (coupled with .NET Core 2.0 SDK) or higher.

The above also links to the following, which provides more info: https://docs.microsoft.com/en-gb/dotnet/standard/net-standard#net-platforms-support

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM