Is there a way to escape colon in appsetting.json dictionary key in aspnetcore configuration?
Asked Answered
M

1

10

I have this provider dictionary in appsetting.json

  "AppSettings": {
      "Providers": {
         "http://localhost:5001": "Provider1",
         "http://localhost:5002": "Provider2"
      },
      "ArrayWorks": [
         "http://localhost:5001",
         "http://localhost:5002"
      ],
      "SoDoesColonInDictionaryValue": {
         "Provider1": "http://localhost:5001",
         "Provider2": "http://localhost:5002"
      }
   }

And the following throw exception because there's colon in the dictionary key.

Configuration.GetSection("AppSettings").Get<AppSettings>()

However, colon works fine as dictionary value, or array, just not dictionary key. I read colon has special meaning in config, but there seems no way to escape. Why?

Edit:

public class AppSettings
{
    public string ApplicationName { get; set; }
    public IDictionary<string, string> Providers { get; set; }
}

When debugging Configuration.GetSection("AppSettings"), you get this

Key    AppSettings:Providers:http://localhost:5000
Value  Provider1

It was intended to be something like this

Key     AppSettings:Providers:http_//localhost_5000

But there seems no way to control how Configuration treat the :::

Motoneuron answered 10/6, 2018 at 21:25 Comment(6)
Is AppSettings.Providers a dictionary type IDictionary<string, string>? Can you post your AppSettings class code.Inglenook
@Inglenook Thanks for the follow up, see Edit.Motoneuron
You don't have a section in your config called AuthorizationProviders. Change the name in config and it should map correctly to AppSettings.Inglenook
Sorry, that's a typo in post only. The issue is Configuration.GetSection insists on splitting by any and all colons in the key, and there's no way to control that since : is a valid json character. So the question is, what if someone needs a dictionary of Urls. I was hoping there's a way escape that into Configuration, like http\://localhost\:5000Motoneuron
You could look into creating your own config provider but I think working around this obscure limitation is the better way to go. You could write your keys with underscores and then convert them to colons when they are read e.g. services.Configure<AppSettings>(opts => {}) is not executed until first called upon by the IOptions service in your code.Inglenook
Also see #52121874Parathion
D
8

Edit: According to aspnet/Configuration#792

Colons are reserved for special meaning in the keys, so they shouldn't be used as part of normal key values.

  • This isn't supported and issue was closed.

  • Not yet, Until now there is no escape colon character, Accourding to Microsoft Asp.net repository on github, but there is an open issue with #782 on the github repository which move it to this backlog

As a workaround you can reverse the key with the value in appsetting:AppSettings and correct it in code like the below:

"AppSettings": {
  "Providers": {
     "Provider1":"http://localhost:5001",
     "Provider2":"http://localhost:5002"
  },
  "ArrayWorks": [
     "http://localhost:5001",
     "http://localhost:5002"
  ],
  "SoDoesColonInDictionaryValue": {
     "Provider1": "http://localhost:5001",
     "Provider2": "http://localhost:5002"
  }
}

And in code make sure to reverse dictionary key and value as the below

 var result = _configuration.GetSection("AppSettings:Providers")
               .GetChildren().ToDictionary(i=>i.Value,i=>i.Key);
      // result["http://localhost:5001"] return Provider1
      // result["http://localhost:5002"] return Provider2
Deration answered 31/3, 2020 at 21:57 Comment(2)
Nice solution, flipping the key/valueLeucoderma
This is not a solution if your values are complex objects, not just strings.Deanery

© 2022 - 2024 — McMap. All rights reserved.