Azure function uses incorrect DLL version - c#

I have created an Azure function that is called via webhook from Dynamics 365. A simple scenario to read the remote context object does work; however, a more complex scenario throws an error. Tried to get an instance of the Dynamics service object using CrmServiceClient (Microsoft.Xrm.Tooling.Connector) but it throws an error when this line runs CrmServiceClient client = new CrmServiceClient(crmConnectionString):
"Could not load type 'Microsoft.IdentityModel.Clients.ActiveDirectory.PromptBehavior' from assembly 'Microsoft.IdentityModel.Clients.ActiveDirectory, Version=3.14.2.11, Culture=neutral, PublicKeyToken=31bf3856ad364e35'"
I have checked the DLLs in the bin directory in Azure and the version for Microsoft.IdentityModel.Clients.ActiveDirectory is 2.22.
Also, I checked the xxx.deps.json file in Azure and it shows the same version:
"Microsoft.IdentityModel.Clients.ActiveDirectory/2.22.0.0": {
"runtime": {
"Microsoft.IdentityModel.Clients.ActiveDirectory.dll": {
"assemblyVersion": "2.22.0.0",
"fileVersion": "2.22.30211.1727"
}
}
I have searched for version 3.14.2.11 for the mentioned DLL but cannot find it. So I wonder why is Azure loading that version?
Following the advice of some other postings, I have added a file -function.proj- under my function's folder with the idea to downgrade the version of that DLL that Azure loads, here's the content:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.IdentityModel.Clients.ActiveDirectory" Version="2.22.0" />
</ItemGroup>
</Project>
Unfortunately, it hasn't changed the outcome. Has anyone run into the same issue?

The package Microsoft.Xrm.Tooling.Connector is depend on .net framework 4.6.2, while your azure function TargetFramework is netstandard 2.0. So make sure your function's runtime version.
Then upgrade Microsoft.IndentityModel.Client.ActiveDirectory to 2.28.3 version.
If your function runtime is ~1, create project.json with following content.
{
"frameworks": {
"net46":{
"dependencies": {
"Microsoft.IdentityModel.Clients.ActiveDirectory": "2.28.3"
}
}
}
If your function runtime is ~2, create function.proj as below.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.IndentityModel.Client.ActiveDirectory" Version="2.28.3"/>
</ItemGroup>
</Project>

Just downgrading the runtime to version 1 did the trick.

Related

.NET Core - why do 'classic' assembly references not get put into the generated <app>.deps.json files at a higher level?

In .NET core, the generated .deps.json file controls assembly loading - if your dependencies aren't in the .deps.json for your top level application, they will not get loaded unless you start handling AssemblyResolve events and all that stuff.
The situation I have is as follows
.NET Core 6
Class Library Assembly - lets call it 'ClassLib'
Application (exe) - lets call it 'App' - that depends on 'ClassLib' as a project reference
If I use a Nuget package (PackageReference) inside ClassLib then the Nuget package shows up in the generated App.deps.json and everything works. (Newtonsoft.json used as an example of this below)
However, I have several cases where there are legacy assemblies that I wish to reference that are not in Nuget packages. Those can be added as references using the UI (Add COM Reference then 'Browse' to the assembly) or via a <Reference ...> node in the csproj.
When you build 'App', the App.deps.json does not include any sign of the dependencies on the legacy assemblies via ClassLib, just the nuget packages. This means that at runtime, the legacy assembly is not going to get loaded, leading to all sorts of interesting failures...
Details of the situation
ClassLib.csproj contents
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
</ItemGroup>
<ItemGroup>
<Reference Include="Legacy">
<HintPath>..\path\to\Legacy.dll</HintPath>
<SpecificVersion>True</SpecificVersion>
</Reference>
</ItemGroup>
</Project>
App.csproj contains
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\ClassLib\ClassLib.csproj" />
</ItemGroup>
</Project>
Generated App.deps.json shows the dependency of ClassLib on NewtonSoft.Json (imported as Nuget) but not on Legacy.dll
"ClassLib/1.0.0": {
"dependencies": {
"Newtonsoft.Json": "13.0.2"
},
"runtime": {
"ClassLib.dll": {}
}
}
I have tried various combinations of options in the node such as CopyLocal/Private etc with no change to the outcome in terms of the generated App.deps.json
I can make things work if I pack Legacy.dll into a nuget package, but to be honest I have a number of legacy dlls to deal with and making each into a nuget package (they come from various sources and may be updated separately) seems rather a 'sledgehammer to crack a nut' solution.
so...
Is there a way that I can persuade the build system to treat the old-fashioned assembly reference in the same way as the package reference and propagate the dependencies up to higher level projects? Failing that, is there a way that you can customize the build process to inject dependencies into the .deps.json file at build time? (hey, a different sort of dependency injection!) Or am I stuck making nuget packages or hacking around in AssemblyResolve events?

Cannot Migrate Blazor App to .Net 5 Due to System.Runtime Error

I have been working through an awesome tutorial within Udemy to learn more about Blazor (https://www.udemy.com/course/programming-in-blazor-aspnet-core/), but have hit a stumbling block that I'm not entirely sure what to do with.
Short Version
When upgrading to .Net 5 from .Net Standard 2.1, I end up with this error when trying to run this sample Blazor application as soon as it loads up (so it's not hitting any of my code): System.TypeLoadException: Could not resolve type with token 01000014 from typeref (expected class 'System.Threading.Tasks.Task' in assembly 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a') I see a similar problem with this SO link, but it didn't really give me much to go off of.
Detailed Version
With prior versions of .Net, you installed the latest, then Visual Studio picked that up, you switched projects and away you went - everything was seamless and just worked. With some of the newer stuff though, Microsoft's messaging has been extremely confusing and the problem I'm hitting now is inside that Udemy tutorial I need to utilize the IJSObjectReference interface to do something. When I first added that to the code, the type reference couldn't be resolved so a quick search pointed me to needing to move the project to .Net 5 by changing this:
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
</PropertyGroup>
to this (because Visual Studio doesn't always show .Net 5 as an option):
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
Seemed simple enough, so I changed the Client Blazor project to this and tried to compile. That gives me this error: Project BlazorMovies.Client is not compatible with netcoreapp3.1 (.NETCoreApp,Version=v3.1). Project BlazorMovies.Client supports: net5.0 (.NETCoreApp,Version=v5.0). I figured okay, I'll bump Server to 5.0 next and then everything compiles fine, but as soon as I pull it up, I get this error: System.TypeLoadException: Could not resolve type with token 01000014 from typeref (expected class 'System.Threading.Tasks.Task' in assembly 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'). Then I remembered not recalling if I'd installed .Net 5 yet, so I went to check and (via learn.microsoft.com) I only have 4.8.03752 installed. I then did some searches to try and find the .Net installers and there were multiple (see here) - even the layout of the page is really overwhelming, with ~20 install links scattered throughout. I knew I needed at least x64, so I first installed the SDK since it said Visual Studio support and that went significantly faster than I expected (based on prior installs of .Net), but now VS is showing .Net 5 which seemed promising! I re-checked the registry though, and it still says 4.8.03752 and when I went to Add/Remove programs, .Net 5 doesn't show up like all the other versions. I next installed the Hosting Bundle which said it was successful, but the sample app still has the exact same error.
Any advice? I know Blazor is quite new, but with Microsoft's extremely confusing messaging between .Net Framework, .Net Standard, .Net Core and now a migration back into .Net 5 that seems to need multiple installers, I don't really know where to go next. That error is entirely generated from within the Web Assembly code according to the stack trace, so it doesn't appear to be anything related to what I'm doing. Here's a screenshot of everything Chrome shows me in the console:
To migrate Blazor Webassembly Application from netstandard2.1 to .NET 5, you could refer the following steps:
Install or update Visual Studio 2019 to version 16.8.0+, and install the .NET 5 SDK.
Change the Blazor Webassembly project setting.
Create a Blazor Webassembly project (When create the application, select .net core 3.1, then, the TargetFrameWork will be .netstandard2.1), Open the application .csproj file:
Update the SDK from Microsoft.NET.Sdk.Web to Microsoft.NET.Sdk.BlazorWebAssembly
Set the TargetFramework to net5.0
In case you have it, remove the package reference to Microsoft.AspNetCore.Components.WebAssembly.Build.
After updating, the .csproj file content as below:
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="3.2.1" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="3.2.1" PrivateAssets="all" />
<PackageReference Include="System.Net.Http.Json" Version="3.2.0" />
</ItemGroup>
</Project>
Update the Nuget dependencies version.
The result like this:
Then, the final .csproj file content looks as below:
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="5.0.2" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="5.0.2" PrivateAssets="all" />
<PackageReference Include="System.Net.Http.Json" Version="5.0.0" />
</ItemGroup>
</Project>
Clean the entire solution, otherwise the build engine won’t be able to re-generate all the required files with the updated framework.
Then running the application, the website works well.
Have you changed the header node in the *.csproj too?
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
...
</Project>

Unable to install nuget package into azure function

I am just starting to use Azure functions in the logic apps.I have created a function that i am trying to use a Nuget package HTMLAgilityPack and getting it install via the console (in classic view). But it mentions that no project found?
To use NuGet packages in a 2.x and later C# function, upload a function.proj file to the function's folder in the function app's file system. Here is an example function.proj file that adds a reference to HtmlAgilityPack version 1.11.24:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="HtmlAgilityPack" Version="1.11.24" />
</ItemGroup>
</Project>
And add using HtmlAgilityPack; above the code, refer to the snapshot as below:

Error on published ASP.NET core site: Cannot find compilation library location for package 'Microsoft.AspNet.WebApi.Client'

My webb app works fine when run from Visual Studio, but when I publish and try to load a page, I get:
InvalidOperationException: Cannot find compilation library location for package 'Microsoft.AspNet.WebApi.Client'
Microsoft.Extensions.DependencyModel.CompilationLibrary.ResolveReferencePaths(ICompilationAssemblyResolver resolver, List assemblies)
I've been stuck on this for quite a while. I've attempted to apply the various workarounds in the thread https://github.com/dotnet/core-setup/issues/2981, but none of them have worked.
My csproj file is pasted below. I'm not sure what other information would be useful:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<UserSecretsId>aspnet-CrowdQuery2-8C668DB3-5C80-4D9E-851D-2434D0CDA7E9</UserSecretsId>
<PublishWithAspNetCoreTargetManifest>false</PublishWithAspNetCoreTargetManifest>
</PropertyGroup>
<PropertyGroup>
<RuntimeFrameworkVersion>2.1.2</RuntimeFrameworkVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.6" />
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.1.3" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>
<Folder Include="ViewModels\" />
</ItemGroup>
</Project>
I've been having the same issue using Microsoft Azure.
The solution in this case was to clean up the wwwroot folder in our web app using Kudu (Development Tools -> Advanced Options), because there were some old DLLs still left from before the upgrade to .NET Core 2.1, because .NET Core 1 publishes the DLLs to the wwwroot folder, whereas in 2.1, the DLLs are loaded from a global store.
After having completely emptied the wwwroot folder, and redeploying the app, the error was resolved and the app ran as expected.
I had to
(1)
Edit .csproj and add
<PropertyGroup>
<MvcRazorExcludeRefAssembliesFromPublish>False</MvcRazorExcludeRefAssembliesFromPublish>
</PropertyGroup>
(2)
Change the publish "Target Runtime" to "win-x64" (it was previously x86). I don't know why this is required, because my project properties -> Platform target is "Any CPU".
(I have two other similar websites in the same solution, neither of those .csproj files require that line, and both are still publishing to x86).

How to predict/score XGBoost or LightGBM in .NET Framework 4.6.1 application

I have a machine learning problem where I have obtained very good results on training/test data using both LightGBM and XGBoost. The next step is to obtain predictions from one of these models into an existing C# application (.NET Framework 4.6.1) Is there any library that can help me do this? What I have tried so far:
ML.NET: Should work for LigthGBM, but due to this bug it works only for .NET Core.
Windows.ML: This should be able to predict an ONNX model, and I managed to create an ONNX model from my XGBoost model. But Windows.ML seems to work only for UWP apps, at least all samples are UWP.
SharpLearning: This library has an interface to XGBoost. Unfortunately, it does not support sample weights, which I rely upon.
CNTK: Tried to load the ONNX file (similar to this example), but get: Error: ONNX (TreeEnsembleClassifier) is not supported in CNTK.
Any suggestions, or do I have to wait for ML.NET to fix the bug?
I was able to use LightGBM in a net461 console application. The above bug only occurs if you are using packages.config to manage your NuGet packages. In order to work around the listed bug in the LightGBM nuget package, you can take one of the following approaches:
Use a new "SDK-style" .csproj, but set the TargetFramework to net461.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net461</TargetFramework>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.ML.LightGBM" Version="0.3.0" />
</ItemGroup>
<ItemGroup>
<None Update="iris-data.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
Change your normal .NET Framework .csproj to use <PackageReference> instead of packages.config. You can do this in the Package Manager Settings under Tools -> NuGet Package Manager menu. "Default package management format". You can refer to the Migrate from packages.config to PackageReference document for more info.
<ItemGroup>
<PackageReference Include="Microsoft.ML">
<Version>0.3.0</Version>
</PackageReference>
<PackageReference Include="Microsoft.ML.LightGBM">
<Version>0.3.0</Version>
</PackageReference>
</ItemGroup>

Categories