Azure Functions V1 linking wrong version of the RestSharp.dll - azure

Guys I know that the azure functions cli has a dependency with RestSharp.dll and I think that is conflicting with one of my Azure Functions.
I am getting a runtime type exception
System.TypeLoadException: 'Could not load type 'RestSharp.IAuthenticator' from assembly 'RestSharp, Version=105.2.3.0, Culture=neutral, PublicKeyToken=null'.'
Now my azure function is dependent on RestSharp nuget Version 104.4.0.0. There is no reference in my project to Version 105.2.3.0. Here is the interesting thing. In my despair I searched my entire computer for the culprit dll version 105.2.3.0 and I found it at AppData\local\Azure.Functions.Cli\1.0.12
Is that it ? Is the Azure functions runtime trying to link with its RestSharp.dll version instead of the dll version of my project ?

Runtime should technically load version 104.4.0.0. However it is still loading the version referred by the runtime (105.2.3.0). I was able to verify this behavior. Have filed a bug for this https://github.com/Azure/azure-functions-host/issues/2832.
In the meantime is it possible to do one of the following:
Update the code to use 105.2.3.0, I see RestSharp.IAuthenticator type is present. It is under a different namespace. There should be another method exposing the same functionality
If the function app is not being used in prod. You could use the beta runtime. You should not encounter this issue in beta runtime (v2.x)

Related

ImageMagick on Azure Functions cannot load native library

I'm trying to use Magick.NET library to do image processing on Azure Functions.
I have tried the same code in a Console App (.NET Core 3.1) which works without any issues. However when running the same code in an Azure Functions Project, I get the following error.
Code:
var image = new MagickImage(File.ReadAllBytes(#"<My Image Path>"));
Exception:
System.TypeInitializationException: 'The type initializer for 'NativeMagickSettings' threw an exception.'
StackTrace:
at ImageMagick.MagickSettings.NativeMagickSettings..ctor()
at ImageMagick.MagickSettings..ctor()
at ImageMagick.MagickImage..ctor()
at ImageMagick.MagickImage..ctor(Byte[] data)
at FunctionApp2.Function1.Run(TimerInfo myTimer, ILogger log) <-- My Code
Inner Exception:
Unable to load DLL 'Magick.Native-Q8-x64.dll' or one of its dependencies: The specified module could not be found. (0x8007007E)
Inner Exception StackTrace
at ImageMagick.Environment.NativeMethods.X64.Environment_Initialize()
at ImageMagick.Environment.NativeEnvironment.Initialize()
at ImageMagick.Environment.Initialize()
at ImageMagick.MagickSettings.NativeMagickSettings..cctor()
I believe this is due to the way Azure Functions package is organized and the path Magick.NET is looking for its native binary to load. I can confirm that the native binary is written at \bin\Debug\netcoreapp3.1\runtimes\<platform>\native when the Function app is built.
I have traced the apps using ProcessMonitor for each app and can see Function app looks in the wrong location.
It looks in
\bin\Debug\netcoreapp3.1\ bin\ runtimes\[platform]\native
instead of
\bin\Debug\netcoreapp3.1\runtimes\[platform]\native
(Below traces are filtered to only show path contains Magick.Native and process name filtered to the Console app exe and func.exe)
Console App Trace
Function App Trace
I have also tried setting MagickAnyCPU.CacheDirectory to Directory.GetCurrentDirectory() but it hasn't helped.
UPDATE:
After building, if I copy \netcoreapp3.1\runtimes folder to \bin this fixes the problem, but I current don't want to rely on that trick if there's a proper workaround.
UPDATE 2:
This issue appears to happen only when using
<TargetFramework>netcoreapp3.1</TargetFramework>
and Microsoft.NET.Sdk.Functions version 3.0.x
It does not appear when using older versions. I have successfully used
<TargetFramework>netcoreapp2.1</TargetFramework>
and Microsoft.NET.Sdk.Functions version 1.0.x
without this issue.
So, is there a workaround to get ImageMagick to load native lib from the right place?
Potential Workaround is to get msbuild to copy the runtimes folder after the build completes.
Add following to csproj
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="xcopy /Y /E $(OutDir)runtimes\ $(OutDir)bin\runtimes\" />
</Target>
or right click project > properties > Build Events and paste the above command to post build event command line
This will copy all of the runtimes binaries, not just the one we want, increasing the size of final build.
UPDATE:
This may be a bug in Microsoft.NET.Sdk.Functions version 3.0.8.
These issues in the github repo are tracking this.
Version 3.0.8 places the runtimes folder incorrectly
Microsoft.Data.SqlClient is not supported on this platform with Microsoft.NET.Sdk.Functions 3.0.8
This seems to only happen when using Microsoft.NET.Sdk.Functions version 3.0.8 which seems to have only just appeared in nuget on Friday. I will instead downgrade to 3.0.7.
Alternatively if you don't want to downgrade,
You could use MagickNET.SetNativeLibraryDirectory as a work around

Azure Function gives error: System.Drawing is not supported on this platform

(If this question is poorly worded, could someone please help me clear it up?)
I have an Azure Function (2.0) which relies on some System.Drawing code. I've added a NuGet reference to System.Drawing.Common (4.5.0).
After publishing the app, however, when the function is called, it produces the error:
System.Private.CoreLib: Exception while executing function:
[MyFunctionName]. System.Drawing.Common: System.Drawing is not
supported on this platform.
As far as I'm aware, System.Drawing.Common is supported on .NET Core now, which I believe is the environment in which my Azure Function is running. The actual project is a .NET Standard 2.0 project, though.
I am confused as to how to resolve this. I've tried converting the project to a .NET Core 2.1 project but that led to bizarre errors related to "Metadata generation failed" and an inability to find System.Runtime.
My project references Microsoft.Azure.WebJobs.Extensions.EventGrid (2.0.0-beta2) if that's relevant.
It's not about the CLR, it's about the sandbox.
System.Drawing relies heavily on GDI/GDI+ to do its thing. Because of the somewhat risky nature of those APIs (large attack surface) they are restricted in the App Service sandbox.
Win32k.sys (User32/GDI32) Restrictions
For the sake of radical attack surface area reduction, the sandbox prevents almost all of the Win32k.sys APIs from being called, which practically means that most of User32/GDI32 system calls are blocked. For most applications this is not an issue since most Azure Web Apps do not require access to Windows UI functionality (they are web applications after all).
Try to find an different library that doesn't rely on System.Drawing/GDI, like ImageSharp.
A little update can help a lot of people.
Now you can switch your Azure Function to v3:
in Function app settings panel -> Runtime version ~3
With this setup, your code run in a sandbox that support Core 3, (you don't need to rebuild your dll to Core3, i run my .net core 2.1 dll without errors), and surprise... you don't get this exception anymore:
System.Drawing.Common: System.Drawing is not supported on this platform.
Because the CLI can found GDI/GDI+ that need in the subsystem.
Now i can convert html to pdf without go crazy.

References within an azure functions project not working

So I have some Azure Functions I need to publish, which I want to do via a functions project. However, those functions rely on references to class libraries within my solution, and the references do not work within a functions project, is there a way around this?
Edit: After adding the references to the other projects, when "using" the namespaces in which the classes are kept, the compiler throws an error "cannot resolve symbol", it is as if the reference does not exist. The functions project will not build because it cannot find the namespace in which the classes exist
Verify that each project targets the same version of .NET framework. I had the same problem until I noticed that the referenced project targeted 4.7.1, but my Azure function project targeted 4.6.1. Changing the referenced project to match the Azure function project resolved the issue.
There are a couple more steps to consume assemblies if they're not exposed by default in Azure Functions. If it's a custom assembly you have to make sure it's included in the bin folder. Then you have to make sure you're using the #r directive. Are you doing both of those things? Include your code header and settings if so.
This page has the list of assemblies that are visible to Azure Functions, some still requiring the #r directive:
https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-csharp#referencing-external-assemblies
The following assemblies are automatically added by the Azure Functions hosting environment:
mscorlib
System
System.Core
System.Xml
System.Net.Http
Microsoft.Azure.WebJobs
Microsoft.Azure.WebJobs.Host
Microsoft.Azure.WebJobs.Extensions
System.Web.Http
System.Net.Http.Formatting
The following assemblies may be referenced by simple-name (for
example, #r "AssemblyName"): Newtonsoft.Json
Microsoft.WindowsAzure.Storage Microsoft.ServiceBus
Microsoft.AspNet.WebHooks.Receivers Microsoft.AspNet.WebHooks.Common
Microsoft.Azure.NotificationHubs

Azure Functions dll version mismatch

We have an Azure function which references an external assembly via a private Nuget feed.
The problem we're having is that we have two different versions of Microsoft.Azure.WebJobs.dll - one which is a dependency of our nuget package and another which I'm assuming is being provided by the runtime.
error CS1503: Argument 2: cannot convert from 'Microsoft.Azure.WebJobs.ICollector<Microsoft.WindowsAzure.Storage.Table.ITableEntity> [D:\Program Files (x86)\SiteExtensions\Functions\1.0.10635\bin\Microsoft.Azure.WebJobs.dll]' to 'Microsoft.Azure.WebJobs.ICollector<Microsoft.WindowsAzure.Storage.Table.ITableEntity>
I found this question which says that binding redirects are not supported:
Azure Functions binding redirect
We could try to remove our dependency on that library, or we could match the version used by Azure Functions, but I think we're going to have the same problem with using Microsoft.WindowsAzure.Storage anyway.
Please advise!
You are correct that binding redirects are not supported. The runtime has its own dependencies on the WebJobs SDK and Storage libraries so objects passed into your functions will be from those versions. I recommend removing your dependencies on other versions and snapping to ours. Note that for these libraries, you don't have to add your own package reference, you can reference ours in your function code via:
#r "WindowsAzure.Storage"
You don't need to add explicit #r references for WebJobs SDK types (e.g. ICollector<T>) - the runtime adds that assembly implicitly. Of course this only applies for function code we're compiling for you, not code coming from your external packages.
In the future we might improve things in this area, but for now you'll be swimming up stream if you try to use conflicting versions.

Assembly not packaged for Azure worker role

I am facing a strange problem with packaging an assembly for Azure worker role. I am building a sample Azure cloud application having one website and a worker role. I am referencing a third party assembly, myasm.dll in both website and worker role project. The myasm.dll has dependency on two other assemblies. When I build the project all three(myasm.dll and two dependent assemblies) third party assemblies are getting copied to bin directory for both website and worker role projects. So far so good.
When packaging is done for worker role, off the three third party assemblies, only two assemblies are included in the package, the third assembly is not included. Strangely enough, packaging of Website project includes all three assemblies. I created one more worker role to test the behavior but same behavior was seen again.
Is this a known issue or something? Any help is highly appreciated.
I use VS2012 Update 4.
Package will not include any dll which is not explicitly used in your project or referenced. I know this problem occurs when you do not use type explicitly in a your project(old bug raised - with won't fix status)
I guess your best option is to explicitly reference those missing dll's (see here) or try to add dummy usage of types from missing dependencies.

Resources