Could not load file or assembly 'AutoMapper, Version=6.1.1.0,
Culture=neutral, PublicKeyToken=be96cd2c38ef1005' or one of its
dependencies. The system cannot find the file specified.
I have two projects: Azure Function Project and Library project. The library project is where the database tables, context defined in it which running .Net Core 2.0 whereas the Azure Function Project run on .Net Framework 4.6.1.
The error occurred when calling the
db.ExecuteProcedureQuery<ApiAttendanceModel>(StoredProcedureName.Sp_GetAttendanceByAttendanceId, out error, parameterList).SingleOrDefault();
Does anyone know what the issue is?
Inside the azure function (trigger by queue), tried to connect to azure table in the code. It fired and exception. So I changed the project back to .net standard 4.6.1
AFAIK, Microsoft.NET.Sdk.Functions depends on Microsoft.Azure.WebJobs which would depends on WindowsAzure.Storage.
Per my test, I could leverage the client SDK to work with Azure Table storage under my Azure Functions v2.
If your Azure Function targets .NET Framework v4.6.1, after you references the Net Core 2.0 class library, your Azure Function project would retrieve the compile errors as follows:
For your scenario, I would recommend you create a class library targets the .Net Standard that allows your library to be called by your Azure Functions v1 (.NET Framework) or Azure Functions v2 (.NET Core). Details you could follow Building a .NET Standard class library with C#.
Moreover, I just created my .Net Standard 1.3 class library to test this issue. You need to choose which .Net Standard version to be targeted, details you could follow here.
Related
In .Net Framework 4.7.2 F#, I have been using:
FSharp.Data.TypeProviders
with
type WSDL = WsdlService<"http://...ServiceHost.svc">
type AV = WsdlService<"http://...ServiceHost.svc">
to access my local WCF network service from an F# .fs file.
How do I access the WCF service from F# client when .NET Core 3.1 is being used?
TIA
If not, what is the recommended upgrade path for WCF/petapoco/PostgreSQL?
That is an old type provider from F# 3.0, and it depended on svcutil for code generation. You could reference its nuget package but it's possible (likely) there is no support for the dotnet-svcutil tool. But you can use WCF from C#, so:
Add a new C# project to your solution
Add Connected Service in Visual Studio and configure your end point, this will generate the necessary code, build your project (and test that it works)
From your F# project, add reference to this C# project, and open ProjectName
Create your type, and use it from F#. You will get intellisense on the types so the user experience is not that different from the type provider.
If needed you can publish the self-contained exe:
dotnet publish -r win10-x64 -c Release -p:PublishSingleFile=true -p:PublishTrimmed=true
My understanding is that, starting with ASP.NET Core 3.0, .NET Framework is an unsupported target framework, and thus you can only run on the .NET Core runtime.
If this is the case, what NuGet packages can be imported into an ASP.NET Core 3 app?
I assume that you could reference any package that targets netstandard, but what about packages that only target the full framework (i.e., a legacy package that only targets net45)?
What happens if the package you import references an assembly that's not part of .NET Core—i.e., System.Drawing?
TL;DR: You can still reference (packages which depend upon) .NET Framework assemblies from .NET Core 3 and even .NET 5, but you will receive a runtime error if you call into any code which relies upon APIs or libraries not (yet) supported by .NET Core. You can discover these using Microsoft's .NET Portability Analyzer
Background
First off, you're correct that ASP.NET Core 3.x applications can no longer target the .NET Framework, as announced by Microsoft in 2018. That capability previously allowed ASP.NET Core applications to call into .NET Framework libraries, and thus offered an intermediate solution for web applications migrating to .NET Core.
Note: Since the .NET Framework only runs on Windows machines, writing ASP.NET Core web applications which targeted the .NET Framework implicitly restricted those applications to running on Windows.
Behavior
Even when targeting .NET Core or now .NET 5, however, you're still able to reference .NET Framework packages and assemblies, assuming you're on a Windows machine and have the corresponding .NET Framework installed. The inner workings of this are a bit involved, but the short of it is that .NET Core and .NET 5 will evaluate .NET Framework assembles as though they are .NET Standard assemblies. If the API call is also implemented in the .NET Core runtime, it will work fine—but if the API call is exclusively part of .NET Framework, you'll receive an exception.
Surprise! It's really important to emphasize that this is a runtime exception. You will still be able to reference the .NET Framework assembly, write calls to problematic members, and compile your code without any warnings. But as soon as you call into code dependent on a .NET Framework-specific assembly, you'll receive the runtime exception.
Example
With .NET 3.0, a significant portions of .NET Framework libraries have been ported over to .NET Core. In fact, this includes most of the System.Drawing libraries you referenced as an example—though there are good reasons you may not want to use them. If you dig a bit deeper, however, there are plenty of libraries which remain unsupported. One obvious example is the WebConfigurationManager, which could be used to access configuration settings from web.config files.
.NET Framework Code
So, as an example, let's say you have the following function in a .NET Framework class library, which returns an array of keys from your web.config's <AppSetting>s element:
public static class Configuration
{
public static string[] GetAppSettings() => System.Web.Configuration.WebConfigurationManager.AppSettings.AllKeys;
}
ASP.NET Core Code
And then, in an ASP.NET Core controller, you expose an endpoint to retrieve this data:
public class MyController: Controller
{
public IActionResult ApplicationKeys() => Content(String.Join(", ", Configuration.GetAppSettings()));
}
Exception
In an ASP.NET Core 2.x application targeting the .NET Framework, this will work just fine. In an ASP.NET Core 3.x or ASP.NET Core 5 application, however, you'll receive the following runtime error when you call the /My/ApplicationKeys/ route:
System.TypeLoadException: 'Could not load type 'System.Web.Configuration.WebConfigurationManager' from assembly 'System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.'
Avoiding Surprises
If you're anything like me, this will make you incredibly nervous. You'd much rather receive design-time errors—or, at least, compile-time warnings—as soon as you attempt to call into a library relying upon unsupported code. Fortunately, Microsoft offers a .NET Portability Analyzer, which is also available as a Visual Studio Extension, for exactly this purpose.
As of .NET 5, there's also a compatibility analyzer built into the SDK which will identify calls that are not supported by the .NET 5 runtime on particular platforms. This requires that target libraries explicitly annotate their types with the [SupportedOSPlatform()] attribute, so you won't get any warnings for legacy .NET Framework types. But this will help identify similar types of compatibility issues for libraries targeting a variety of platforms.
Example
If you run the Portability Analyzer on the above sample code, for example, it will output an Excel spreadsheet identifying that T:System.Web.Configuration.WebConfigurationManager is Not Supported in e.g. .NET Core,Version=v3.1 or .NET Standard + Platform Extensions,Version=v2.0.
Note: Microsoft used to offer an API Analyzer as a NuGet package, which promised to provide design-time analysis in Visual Studio. Unfortunately, the code hasn't been updated in two years, and the latest release is 0.2.12-alpha. In my evaluation, it was not effective at identifying issues.
Sample Project
I've put together a sample project on GitHub which demonstrates the above behavior. It includes the following projects:
ASP.NET Core 2.0 Website targeting .NET Framework 4.8
ASP.NET Core 3.1 Website targeting .NET Core 3.1
.NET Framework class library with calls to the legacy WebConfigurationManager
Both ASP.NET Core websites include two endpoints which call into the same .NET Framework 4.8 class library. The first is a "Hello world" example which will execute fine on both projects, since it relies exclusively on common APIs:
http://localhost:5000/Basic/Index
The second will fail on the ASP.NET Core 3.1 project, since it calls into the legacy WebConfigurationManager API:
http://localhost:5000/Basic/Configuration
Disclaimer: This is a quick and dirty repository that I put together to verify my understanding prior to posting this. If there's interest, I'll tidy it up and document it. For now, however, it may prove useful for those of you who need to see this in action.
Acknowledgments
#Chris Pratt offered an excellent answer covering similar material last year. It's worth reading.
I'm building a Web API in .NET Core 2. I'm using some custom nuget packages to leverage their built in functionality. These custom packages were built against an older .NET version (4.6.1). The problem is some of these packages have references to the old System.Web dll. I'm getting this warning on some of the custom packages in the solution
package was restored using '.net framework version=v4.6.1 instead of using the proj target framework.
The app is also throwing this exception below when I call code in one of the custom packages
System.IO.FileNotFoundException: Could not load file or assembly System.Web.ApplicationServices, Version=4.0.0.0, Culture=neutral,The system cannot find the file specified
Is there any way around this other than re-writing the code in my web Api?
No. System.Web is completely incompatible with Core. While Microsoft opened up NuGet packages that target .NET Framework to be utilized in with .NET Core, it did so based only on .NET Standard 2.0 compatibility, and makes no assurances that the packages will function in part or whole. You'll actually get a warning during compile telling you as much. Also, while you can actually have something like an ASP.NET Core app actually target .NET Framework, again, compatibility of third-party components is not guaranteed, simply because they target the same framework.
Long and short, if there's any dependency on System.Web at all, you can't use it.
In my solution I have an ASP.NET Core 2 MVC app using Razor pages, a Web API 2 app and a .NET 4.7.1 class library containing services and their definitions that use Azure Table Storage from the Azure Storage NuGet (v8.7.0). I'm using autofac for dependency injection.
I have hooked up both my web apps to use classes from my library using Autofac's dependency injection. The Web API app works fine but the Core app doesn't. When I build without installing the Azure Storage NuGet package into the Core app I get the following error:
X.Library' with identity 'X.Library, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null' uses 'Microsoft.WindowsAzure.Storage,
Version=8.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
which has a higher version than referenced assembly
'Microsoft.WindowsAzure.Storage' with identity
'Microsoft.WindowsAzure.Storage, Version=8.1.4.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35
Which leads me to believe that ASP.NET Core 2 apps have Azure Storage pre-installed - I can't find any reference to it in the project though! Weird.
So I have tried to fixed this by installing the Azure Storage (v8.7.0) package which matches the version installed in the library I am using into my Core app. The app now builds and my dependencies are injected but when I try to use them I get MissingMethodExceptions for the methods CreateIfNotExists and CreateQuery. While my Web API app can query Azure Table Service my Core app can't use the same methods to do so.
After some research it seems that the ASP.NET Core implementation of the Azure Storage library has removed some synchronous methods and at runtime it uses this version rather than the .NET Framework compatible version my library references.
Is there any way to remove Azure Storage from the ASP.NET Core 2 app? Is it preinstalled, as I suspect?
I guess the easiest way to fix it is to use methods that are present in the Framework and Core implementations, is this how you'd fix it?
I found a solution to this problem with the help of this blog post: https://weblog.west-wind.com/posts/2017/Jun/22/MultiTargeting-and-Porting-a-NET-Library-to-NET-Core-20
The post talks you through the process of porting a .Net Library to a .Net Standard library that targets multiple runtime versions. This turns out to be exactly what I needed to do.
I took my service that I had written in .Net framework 4.5.1 and copied the files to a new .Net Standard library I created. I then changed the target frameworks to support multiple runtime versions manually (you can't do this using the Visual Studio UI at time of writing). For my purposes I used the following to support .Net Core 2, .Net Standard and .Net 4.7.0:
<PropertyGroup>
<TargetFrameworks>netcoreapp2.0;netstandard2.0;net47</TargetFrameworks>
</PropertyGroup>
The framework you write first is the one that is targeted but I found that Visual Studio gave me errors for methods that weren't available in all versions of the Azure Storage library so I was able to write a service which worked on all three without writing any runtime-specific code.
I installed Windows Azure Storage SDk from nuget. Added the references to my project.
When I make the following reference in my code:
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage.Blob;
I get an exception of: the type or namespace 'WindowsAzure' does not exist in the namespace 'Microsoft (are you missing an assembly reference)'?
researching the issue, I read in this blog that it targets 4.0 framework:
http://www.milosev.com/index.php/93-azure/252-the-type-or-namespace-name-windowsazure-does-not-exist-in-the-namespace-microsoft-are-you-missing-an-assembly-reference
I want use the Azure storage to upload files, is possible to do it with net 3.5? Any alternatives, my site is hosted on Azure?
The blog post you reference is really saying that you cannot target the Client Profile. Make sure your project target Framework is .NET 3.5 and not .NET 3.5 Client Profile.
It can definitely work in .NET 3.5. We use Azure storage in a project that targets .NET 3.5.
If that is not the issue, with the latest Azure Storage client, does it include binaries for .NET 3.5? If not, you may have to download and install and older version.
http://azure.microsoft.com/en-us/downloads/archive-net-downloads/