15

I have these entries in my local.settings.json

{
    "IsEncrypted": false,
    "Values": {
        "AzureWebJobsStorage": "whateverstorageaccountconnectionstring",
        "FUNCTIONS_WORKER_RUNTIME": "dotnet"
    },
    "BusinessUnitMapping": {
        "Values": {
            "Connections": "CON",
            "Products": "PRD",
            "Credit & Affordability": "CAA",
            "Accounts Receivable": "ARC",
            "Identity":  "IDT"
        }
    }
}

I have this code to read the values in startup

services.Configure<BusinessUnitMapping>(options => configuration.GetSection("BusinessUnitMapping").Bind(options));

where BusinessUnitMapping is

public class BusinessUnitMapping
{
  public Dictionary<string, string> Values { get; set; }
  public BusinessUnitMapping()
  {
      Values = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
  }
}

when the I run the function app locally, it can read these settings into BusinessUnitMapping without any issue.

Advanced Edit for Application Settings in Azure Portal only allows simple Key Value pair as below

[
  {
    "name": "AzureWebJobsDashboard",
    "value": "DefaultEndpointsProtocol=Somevalue",
    "slotSetting": false
  },
  {
    "name": "AzureWebJobsStorage",
    "value": "DefaultEndpointsProtocol=Somevalue",
    "slotSetting": false
  },
  ...
]

The questions

  1. Is this a correct approach to store the complex app settings in Azure Function?
  2. How do I get BusinessUnitMapping configured in Azure Portal for the Function App that I have deployed?

-Alan-

Alan B
  • 2,219
  • 4
  • 32
  • 62

2 Answers2

6
  1. Is this a correct approach to store the complex app settings in Azure Function?

This is still an open question: see this github issue asking exactly this

  1. How do I get BusinessUnitMapping configured in Azure Portal for the Function App that I have deployed?

My current preferred approach is to use the options pattern with a delegate that uses GetEnvironmentVariable which will work both locally and in Azure. The downside is that you can't create complex types in the local settings file itself, but your object can be as complex as you like.

A simple example:

In local.settings.json:

{
  ...
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    ...
    "SomeSection:Setting1": "abc",
    "SomeSection:Setting2": "xyz",
  },
  ...
}

In your startup:

services.Configure<MySettingsPoco>(o =>
{
    o.Setting1 = Environment.GetEnvironmentVariable("SomeSection:Setting1");
    o.Setting2 = Environment.GetEnvironmentVariable("SomeSection:Setting2");
});

Then in Azure you can create these settings as follows:

enter image description here

Matt
  • 12,569
  • 4
  • 44
  • 42
  • 3
    Not sure if this is a new change but I'm unable to create settings with ':' in their names, in my Function App. – Tobias Dec 29 '19 at 15:11
  • 3
    Turns out using ':' as a delimiter is unsupported in Linux-hosted Function apps. I made it work by using '__' (double underscore) instead. – Tobias Dec 29 '19 at 16:14
  • 1
    From the docs: "Values must be strings and not JSON objects or arrays. Setting names can't include a colon (:) or a double underline (__). These characters are reserved by the runtime." https://learn.microsoft.com/en-us/azure/azure-functions/functions-run-local?tabs=windows#local-settings-file – LockTar Mar 03 '20 at 13:40
  • 4
    Is there any way to add dictionaries to settings? – Piotr Perak Jun 04 '20 at 09:35
  • @PiotrPerak Unfortunately, not via local.settings.json (at least in Linux-hosted functions). I encourage you to add a separate json file (like appsettings.Development.json) and configuring app to load config from there. That saves all the troubles – karolgro Aug 01 '23 at 10:10
-1

1. Is this a correct approach to store the complex app settings in Azure Function?

We can save these entries in the app settings. For more details, please refer to the document. The detailed steps are as below.

Set app settings on Azure Portal enter image description here enter image description here

2. How do I get BusinessUnitMapping configured in Azure Portal for the Function App that I have deployed?

According to my test, we can use the following code to do that

#r "Newtonsoft.Json"

using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using System.Collections.Generic;
public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
{
    log.LogInformation("C# HTTP trigger function processed a request.");
    var test =Environment.GetEnvironmentVariable("test",EnvironmentVariableTarget.Process);
    log.LogInformation(test);
    var values= JsonConvert.DeserializeObject<Dictionary<string, string>>(test);
    var businessUnitMapping = new BusinessUnitMapping();
    businessUnitMapping.Values = values; 
    log.LogInformation(businessUnitMapping.Values["Products"]);
    string name = req.Query["name"];

    string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
    dynamic data = JsonConvert.DeserializeObject(requestBody);
    name = name ?? data?.name;

    return name != null
        ? (ActionResult)new OkObjectResult($"Hello, {name}")
        : new BadRequestObjectResult("Please pass a name on the query string or in the request body");
}

public class BusinessUnitMapping
    {
        public Dictionary<string, string> Values { get; set; }
        public BusinessUnitMapping()
        {

        }
    }

enter image description here

Jim Xu
  • 21,610
  • 2
  • 19
  • 39
  • 2
    This doesn't work. I don't know if it's changed, but for a V2 function, { "prop":"value"} does not deserialize (or whatever is happening) into a dictionary – A.Rowan Jan 18 '20 at 16:46