2

I am just getting started with C# and I'm a little stuck.

How do I create a dictionary that contains a mix of string,string, string,int, and string,object?

this is what it would look like:

var values = new Dictionary<????>
{
    "key0": 
         {
         "key1": "stringValue1",
         "key2": "stringValue2",
         "key3": "stringValue3",
         "key4": 10000
         },
    "key5": "stringValue4",
    "key6": "stringValue5"
};

I am using this as the body for a POST request. Sample code from here

var body = new FormUrlEncodedContent(values);

var url = "http://url.com/endpoint"

var resp = await client.PostAsync(url, body);

var respString = await response.Content.ReadAsStringAsync();
jgozal
  • 1,480
  • 6
  • 22
  • 43

3 Answers3

3

This is what you said in your comment:

please note that I come from a JavaScript background where you can do whatever you want with a dictionary.

Yes you can do that in JavaScript but you need to learn and understand that C# is a strongly typed language. That does not mean you have to be strong to type it, but it means the types are known at compile time (mostly). Please read into that.

Anyhow, to do what you want to do, you can do it with a Dictionary but it will not be pretty and your fellow C# developers will not be happy with you. So how about you give your keys and values some context by creating a class (OOP). Something like below:

public class Rootobject // Give it a better name
{
    public Key0 key0 { get; set; }
    public string key5 { get; set; }
    public string key6 { get; set; }
}

public class Key0
{
    public string key1 { get; set; }
    public string key2 { get; set; }
    public string key3 { get; set; }
    public int key4 { get; set; }
}

Now you have your class so you can create one or more instances of it:

var ro = new Rootobject();
ro.key5 = "stringValue4";
ro.key6 = "stringValue5";
var key0 = new Key0();
key0.key1 = "stringValue1";
key0.key2 = "stringValue2";
key0.key3 = "stringValue3";
key0.key4 = 1000; // See we cannot put a string here. Different than JavaScript

ro.key0 = key0;

Now you want to POST this and send it over the wire so you need to serialize it. But in your case you need to serialize it to JSON. Therefore, get NewtonSoft so it can do all the heavy lifting for you--again not saying you are not strong. Then all you need to do is this:

var json = JsonConvert.SerializeObject(ro);

Now json will be exactly like this and you can POST it to wherever:

{
  "key0": {
    "key1": "stringValue1",
    "key2": "stringValue2",
    "key3": "stringValue3",
    "key4": 1000
  },
  "key5": "stringValue4",
  "key6": "stringValue5"
}

How did I create the class?

The class above named RootObject, you can either create it manually or ask Visual Studio to do it for you. I am lazy so I asked Visual Studio to do it. If you are lazy then see my answer here.

CodingYoshi
  • 25,467
  • 4
  • 62
  • 64
  • 1
    What kind of joke is this? A downvote? Please explain or I will be ignorant for the rest of my life and you dont want that, do you?. – CodingYoshi Dec 08 '17 at 06:28
  • Thank you very much for your answer. I do know that C# is a strongly typed language and understand what a strongly typed language is... so feel free to delete that part of your answer. I was only saying that I have a JS background to give everybody some context – jgozal Dec 08 '17 at 06:29
  • I gave you an upvote, not sure who gave you a downvote. Going to try your answer out – jgozal Dec 08 '17 at 06:30
  • @jgozal Its okay I will leave the part about JS to help someone else. I know you did not downvote but someone did. No worries, it happens. – CodingYoshi Dec 08 '17 at 06:31
  • 1
    there actually was a way to handle this very similar to js. Regarding c# developers not being happy about it. It sometimes depends on the context. If you are rarely about to use the data and it is getting reallly dynamic, it still makes sense to use `Dictonary`. On the other hand, if you would like to reuse the object in several places, would really make sense to create classes and take advantage of strongly typing. – Neville Nazerane Dec 08 '17 at 06:50
  • @NevilleNazerane thanks so much for the insight. What you say makes sense but I would prefer to follow a more OOP approach for this case scenario – jgozal Dec 08 '17 at 06:56
  • @CodingYoshi your answer helped me create the class with the right structure which was the core of my question. I am having a bit of trouble continuing with the rest of the code to make the POST though :(. That part wasn't really part of the question though – jgozal Dec 08 '17 at 06:58
  • for posting, check the link in my answer – Neville Nazerane Dec 08 '17 at 07:14
2

You can use dynamic. However, in the end, form post will convert everything into string, so you might wanna convert int and object into string first. Then, you can just use Dictionary<string, string>

        Dictionary<string, dynamic> Dict = new Dictionary<string, dynamic>();
        Dict.Add("string1", "1");
        Dict.Add("string2", 2);
        Dict.Add("string3", new object());
Ray Krungkaew
  • 6,652
  • 1
  • 17
  • 28
2

Check this link:

HttpClient PostAsJsonAsync request

You can cast it as

var myData = await response.Content.PostAsJsonAsync<Dictionary<string, dynamic>>(...);

Then you can use it as:

string myStr = myData["key5"];

Although I would recommend you make a class with the structure and use the class name within <>

Sample class:

class MyData {
    public MyData2 key0 { get; set; }
    public string key5 { get; set; }
    public string key6 { get; set; }
}

class MyData2 {
    public string key1 { get; set; }
    public string key2 { get; set; }
    public string key3 { get; set; }
    public int key4 { get; set; }
}

Now you can use this as:

 var myData = await response.Content.PostAsJsonAsync<MyData>(...);
Neville Nazerane
  • 6,622
  • 3
  • 46
  • 79
  • Would you mind pointing me to some literature regarding how I should be making a class with the structure to use it within? I wish to follow best practices – jgozal Dec 08 '17 at 05:42