Unable to user Memory Cache with Azure Function App - azure

I have created Azure Function App with Http trigger in that I want to use memory cache from system.runtime namespace to cache the token. but when I run the application its throwing the error " System.Runtime.Caching: Could not load file or assembly 'System.Configuration.ConfigurationManager, Version=5.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. The system cannot find the file specified."
I have made sure the exact version is installed in the project. here is the csproj file.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AzureFunctionsVersion>v3</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.11" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="5.0.0" />
<PackageReference Include="System.Runtime.Caching" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
Here is the bare minimum version of the code where I am facing the issue.
public static class Function1
{
public static MemoryCache accessTokenCache = new MemoryCache("accessToken");
[FunctionName("Function1")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
accessTokenCache.Add("123", "123", new CacheItemPolicy() { Priority = CacheItemPriority.Default });
return new OkObjectResult("");
}
}

above code works fine with system.runtime.caching nuget with version 4.7.0. I have downgraded for now to get it work.
I have also posted the issue in github for further follow up.
https://github.com/Azure/Azure-Functions/issues/1867

Related

.netCore3.1 to .net6.0 function app upgrade - Unable to debug in local (DLL error)

I have been working on to upgrade my function app .netcore3.1 solution to .net6.0. After upgrading the solution and all the packages - when I run the solution in local - it is throwing below error. I am unable to debug the function app in local. It is throwing error in startup.cs class. Any solution for this ?
System.MissingMethodException: 'Method not found: 'Microsoft.Extensions.Configuration.IConfigurationBuilder Microsoft.Azure.WebJobs.Hosting.IWebJobsConfigurationBuilder.get_ConfigurationBuilder()'
.csproj file
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<AzureFunctionsVersion>v3</AzureFunctionsVersion>
<RootNamespace>Unilever.DigitalFactory_SPC_ControlCharts</RootNamespace>
<_FunctionsSkipCleanOutput>true</_FunctionsSkipCleanOutput>
</PropertyGroup>
I have created a Function App with.NET core 3.1 version.
My .csproj for .NET Core 3.1
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AzureFunctionsVersion>v3</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.1.1" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
</Project>
Migrated from .net core 3.1 to .net 6.0, when I tried with the .csproj provided in the code got the below errors.
In .csproj file, Change the AzureFunctionsVersion from v3 to v4.
Update Microsoft.NET.Sdk.Functions NuGet Package to latest version - 4.1.1
Output:
Code for FunctionsStartup in Startup.cs
using Function3Core;
using Microsoft.Azure.WebJobs.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
[assembly: FunctionsStartup(typeof(Startup))]
namespace Function3Core
{
class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
}
}
}
Code for WebJobsStartup in Startup.cs
using Function3Core;
using Microsoft.Azure.WebJobs.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
[assembly: WebJobsStartup(typeof(Startup))]
namespace Function3Core
{
class Startup : IWebJobsStartup
{
public void Configure(IWebJobsBuilder builder)
{
}
}
}

Getting Bindingdata from Azure function .net6 (function v4)

In dotnet5 (function v3) we could fetch the metadata from FunctionContext by calling functionContext.BindingContext.BindingData.TryGetValue("Metadata", out var meta);
However dotnet 6 (v4) does not seem to have this option.
Azure function v3 (.net5)
Can anyone help me out by providing the correct implementation for the new dotnet 6 (v4) functions
To use .net6 with Function V4 we need VS 2022 environment or VS CODE .
I have tried with one simple blobtrigger azure function running with .net 5 and it works fine to fetch the meta data.
using System;
using System.IO;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;
namespace testfuncapp
{
public static class Function1
{
[Function("Function1")]
public static void Run([BlobTrigger("test/{name}", Connection = "AzureWebJobsStorage")] string myBlob, string name,
FunctionContext context)
{
var logger = context.GetLogger("Function1");
logger.LogInformation($"C# Blob trigger function Processed blob\n Name: {name} \n Data: {myBlob}");
}
}
}
OUTPUT:-
And the same code we have tried with .net 6 environment and its works fine as well.
To do that Open VS CODE and update the .csproj file with .net 6 and function runtime version to V4
Install Function runtime v4 in your local .
NOTE: We need to install only one runtime version at our end.
Update .csproj file
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<OutputType>Exe</OutputType>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Storage" Version="4.0.4" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.2.0" OutputItemType="Analyzer" />
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.5.2" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
</Project>
And update the settings.json file to .net 6 and function runtime to V4 then save it .
And then use the command as below:
1- dotnet restore
2- dotnet build
3- func host start
OUTPUT:-
For more information please refer the below links:
BLOG : Migration from Asp.Net Core 5.0 to 6.0
MS Q&A : Migrating Auzre Function runtime version from 3.x to 4.x not working in VS 2019

AppSelfHoseBase generates error when starting in .net 5

I am trying to create an apphost in the testing project of a project created from .net 5.0 react template.
I am getting the error:
OneTimeSetUp: System.TypeLoadException : Could not load type 'Microsoft.Extensions.Primitives.InplaceStringBuilder' from assembly 'Microsoft.Extensions.Primitives, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'.
And the breakpoint inside Configure() isn't hitting.
Same code seems to work fine in a .net 3.1 project.
Here is gist of app host:
public class MainAppHost : AppSelfHostBase
{
public MainAppHost() : base(nameof(MainAppHost), typeof(MyServices).Assembly) { }
public override void Configure(Container container)
{
//having this blank still triggers error
}
}
Seems error is thrown on AppHost.Start(url).
Stack trace:
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) in /_/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeConstructorInfo.cs:line 375
at System.Reflection.ConstructorInfo.Invoke(Object[] parameters) in /_/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInfo.cs:line 18
at NUnit.Framework.Internal.Reflect.Construct(Type type, Object[] arguments) in /_/src/NUnitFramework/framework/Internal/Reflect.cs:line 113
at NUnit.Framework.Internal.TypeWrapper.Construct(Object[] args) in /_/src/NUnitFramework/framework/Internal/TypeWrapper.cs:line 252
at NUnit.Framework.Internal.Commands.ConstructFixtureCommand.<.ctor>b__0_0(TestExecutionContext context) in /_/src/NUnitFramework/framework/Internal/Commands/ConstructFixtureCommand.cs:line 51
at NUnit.Framework.Internal.Commands.BeforeTestCommand.Execute(TestExecutionContext context) in /_/src/NUnitFramework/framework/Internal/Commands/BeforeTestCommand.cs:line 48
at NUnit.Framework.Internal.Execution.CompositeWorkItem.PerformOneTimeSetUp() in /_/src/NUnitFramework/framework/Internal/Execution/CompositeWorkItem.cs:line 262
I saw a similar issue on NUnit github caused by 3.1 and 5.0 installed on same system so I uninstalled all older versions of SDK but it made no difference.
A simple NUnit test without the apphost works fine:
public class SimpleTestClass
{
[Test]
public void SimpleTest()
{
Assert.That(1 + 1 == 2);
}
}
But if I try to create the AppHost then I get the error:
public class SimpleTestClass
{
public SimpleTestClass()
{
var AppHost = new MainAppHost()
.Init()
.Start("http://localhost:5619/");
}
[Test]
public void SimpleTest()
{
Assert.That(1 + 1 == 2);
}
}
The testing and service layer both target .net 5.0 and the project runs fine, I just can't create an AppHost for testing.
Any idea what I am doing wrong?
edit:
I found exact reproduction steps:
x new react-spa TestAppHost
update all packages
run default integration test it will work
right click testing project and select "User Secrets", install prompted package.
run same integration test it now fails with error. Nunit tests without AppHost will still work fine.
Here is project file:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<DebugType>portable</DebugType>
<OutputType>Library</OutputType>
<UserSecretsId>1f094c52-e2b1-44e1-8e3a-9cf5189d8800</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\TestAppHost.ServiceInterface\TestAppHost.ServiceInterface.csproj" />
<ProjectReference Include="..\TestAppHost.ServiceModel\TestAppHost.ServiceModel.csproj" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="5.0.0" />
<PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.17.*" />
<PackageReference Include="ServiceStack" Version="5.*" />
<PackageReference Include="ServiceStack.Kestrel" Version="5.*" />
</ItemGroup>
</Project>
Edit after repro steps provided. The issue is with referencing v5.0.0 of UserSecrets as ServiceStack's .NET Standard 2.0 builds used in .NET 5.0 Apps only references v2.2.0 which you can change it to to resolve the issue, i.e:
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="2.2.0" />
When .NET 6 LTS is out we'll provide a new framework target for all ServiceStack libraries targeting net6.0 which will let you reference the latest dependency versions.
Unfortunately I've never seen this issue or know how to repro it.
Here's a simple way to create an NUnit Integration test project:
$ mkdir SimpleTestCase && cd SimpleTestCase
$ x mix init-test
$ dotnet test
By default this runs the integration test in both .NET 5.0 and .NET Framework v4.7.2, which should result in the test passing in both .NET platforms:
You can change it to only run in .NET 5.0 by replacing:
<TargetFrameworks>net5.0;net472</TargetFrameworks>
with
<TargetFramework>net5.0</TargetFramework>
If that fails, find which versions of .NET Core you have installed:
$ dotnet --list-sdks
3.1.120 [C:\Program Files\dotnet\sdk]
3.1.414 [C:\Program Files\dotnet\sdk]
5.0.104 [C:\Program Files\dotnet\sdk]
Then create a global.json in your project directory with the latest v5 you have installed, e.g:
{
"sdk": {
"version": "5.0.104"
}
}
This ensures that specific .NET version is used to run/test your project, which you can verify by running:
$ dotnet --version

Resharper fails to debug xunit Theory with ClassData

Recently, I tried to run a Theory test case with ClassData as test input. This is a completely normal behavior and it used to work in the past. The provided code works and I can easily run all tests in Visual Studio 2017 (15.9.2) with xunit 2.1 to 2.4.1 and Resharper 2018.2.3.
The Problem: When I try to debug a Theory test, the debugger starts start but stops before stopping my breakpoint in the Theory test case. Resharper shows an error "Unable to find any matching test cases". As far as I could reproduce this error, it only happens when I debug a Theory test case which uses a class (not a primitive type) as T in TheoryData.
TestMethod_StringClassData: Uses StringClassData with TheoryData of type string.
TestMethod_CultureInfoClassData: Does not step into the test case when trying to debug it. The only difference here is, that the test parameter is not a string, but a CultureInfo object.
Test cases to reproduce the error:
public class UnitTest1
{
[Theory]
[ClassData(typeof(StringClassData))]
public void TestMethod_StringClassData(string cultureInfo)
{
}
[Theory]
[ClassData(typeof(CultureInfoClassData))]
public void TestMethod_CultureInfoClassData(CultureInfo cultureInfo)
{
}
public class StringClassData : TheoryData<string>
{
public StringClassData()
{
this.Add("de");
}
}
public class CultureInfoClassData : TheoryData<CultureInfo>
{
public CultureInfoClassData()
{
this.Add(new CultureInfo("de"));
}
}
}
Update 1:
If I create a new VS2017 csproj with Microsoft.NET.Test.Sdk and select TargetFramework netcoreapp2.1, everything works fine again! If I select TargetFramework net47, no more xunit Theory debugging is possible.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
</ItemGroup>
</Project>

External dependencies in Azure functions with netcore

I've been able to get Azure functions written in net core to run. I now have added a reference to "WindowsAzure.Storage" and am now getting loaderexceptions when I use the local test environment ("func host start").
I can not use the default table storage binder as I need to upsert records in different tables.
I use precompiled functions and am developing with VSCode on OSX. I can't find any info if this scenario is supported or not. Is it even possible to get external dependencies working with the 2.0 runtime of Azure functions.
The local SDK/runtime is
Azure Functions Core Tools (2.0.1-beta.21)
Function Runtime Version: 2.0.11370.0
My csproj file
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.WebJobs" Version="3.0.0-beta3" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions" Version="3.0.0-beta3" />
<PackageReference Include="WindowsAzure.Storage" Version="8.6.0" />
</ItemGroup>
<ItemGroup>
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="SearchTwitter\function.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
</Project>
Part of my function
namespace MyProject.Functions
{
public class SearchFunction
{
public async static Task Run(TimerInfo myTimer, Binder binder, TraceWriter log)
{
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(System.Environment.GetEnvironmentVariable("StorageConnection", EnvironmentVariableTarget.Process));
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
CloudTable searchMetaDataTable = tableClient.GetTableReference("SearchMetaData");
await searchMetaDataTable.CreateIfNotExistsAsync();
}
}
Function.json
{
"bindings": [
{
"type": "timerTrigger",
"direction": "in",
"schedule": "0 */15 * * * *",
"runOnStartup": true,
"name": "myTimer"
}
],
"scriptFile": "../MyProject.Functions.dll",
"entryPoint": "MyProject.Functions.SearchFunction.Run"
}
The Azure Storage Namespacee is available by default by the Azure Functions hosting environment. You can find more details here: https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-csharp#referencing-external-assemblies
However, if that’s not what you’re looking for, rest assured that you can consume any external NuGet package by adding it to your Function’s csproj file. For an example on how to do it, check the sample code in this GitHub repo https://github.com/lindydonna/CSharpHttpCore/blob/master/HttpTriggerCore/HttpTriggerCore.csproj
For precompiled functions, WindowsAzure.Storage package comes as sub-dependency of Microsoft.NET.Sdk.Functions, so you don't need to reference it separately.
If you still reference it, and the reference is of a wrong version, you will get conflicts all over the place.
Such care should be taken for any sub-dependency of Microsoft.NET.Sdk.Functions. Otherwise, referencing NuGets is perfectly supported.

Resources