1

I would like to read appsettings file, but I have problem when one property is defined as IDictionary: the values are converted as string.

For example I have in appsettings defined:

  "Queue":{ 
            "Name": "Test1",
            "Durable": true, 
            "Exclusive": false, 
            "AutoDelete": false, 
            "Arguments": {
              "x-expires": 10000,
              "x-overflow": "drop-head",
            }
 },

The class for binding is defined as

public class QueueSettings
    {
        public string Name { get; set; } = "";
        public bool Durable { get; set; } = true;
        public bool Exclusive { get; set; } = false;
        public bool AutoDelete { get; set; } = false;

        public IDictionary<string, object> Arguments{ get;  set; }
    }

and the binding is done as

QueueSettings queueSettings = new QueueSettings();
settings.GetSection("Queue").Bind(queueSettings);

In this example queueSettings.Arguments["x-expires"] is string ("10000"), but I'd like it as integer. How can I set JsonConverter in Net Core services collection? I understand that it does not use NewtonJson so JsonConverter attribute does not help.

Ozzy
  • 304
  • 3
  • 15
  • Are you sure about that? can you check the runtime types of the arguments array? – sommmen Apr 14 '20 at 08:13
  • what if you cast to int - will that throw an exception? i suspect you're tostringing somewhere since the arguments dictionary is a – sommmen Apr 14 '20 at 08:13
  • sure! Key "x-expires" string ; Value "10000" object {string} – Ozzy Apr 14 '20 at 08:21
  • @sommmen I had ToString(), I did comment it but it did not help – Ozzy Apr 14 '20 at 08:26
  • I can only think that because the arguments dictionary is of Dict that it gets changed to a string rather than an int. you could always use Convert.Toint32(...). You need to cast it anyways. And you can create an auto prop. to do that for you: `public int x-expires => Convert.ToInt32(Arguments["x-expires"]);` – sommmen Apr 14 '20 at 08:32
  • I have already added a method like public IDictionary CastedArguments() {...} which gives a new dictionary with casted values where it is possilble to convert to int. But this is a work-around – Ozzy Apr 14 '20 at 08:47
  • of course the same problem is for bool ... – Ozzy Apr 14 '20 at 09:08

1 Answers1

1

You can manually bind if you want as you want.

services.Configure<QueueSettings>(configs =>
{
    configs.Name = configuration.GetSection("Queue").GetValue<string>("Name");
    configs.Arguments.Add("x-expires",  configuration.GetSection("Queue:Arguments").GetValue<int>("x-expires"));
});
cdev
  • 5,043
  • 2
  • 33
  • 32
  • OK but it is still a work-around. I could replace Arguments with class with property int Expires. Im my case IDictionary should give me possibility to pass parameters directly to third-party software. Even in the case in the future a new version of it adds a new parameter, I do not need to rewrite code, in this case the binded class. The problem is there is no possibility to add a custom Json converter. – Ozzy Apr 14 '20 at 15:24
  • or at least the existing converter should distinguish between "x-expires": 10000 (integer), and "x-expires": "10000" (string), – Ozzy Apr 14 '20 at 15:28