0

Hey all I have the following code that I am trying to rename the default values of "KEY" and "VALUE" to "Name" and "Value":

public class jsonOutputStyle
{
    public string Name { get; set; }
    public string Value { get; set; }
}

[Obsolete]
public string POB_CODE()
{
    Dictionary<string, string> _dicts = null;

    try
    {
        using (OracleConnection Oconn = new OracleConnection(connectionORI))
        {
           _dicts = Oconn.Query<KeyValuePair<string, string>>(
                            "SELECT " +
                                "POB_CODE AS Key," +
                                "POB_DESC AS Value " +
                            "FROM " +
                                "POB_CODE " +
                            "WHERE " +
                                "DISPLAY_SORT_ORDER >=1 " +
                            "AND " +
                                "DISPLAY_SORT_ORDER <=60",
                            null
                          )
                   .ToDictionary(pair => new jsonOutputStyle() { 
                        Name = pair.Key, 
                       Value = pair.Value
                   });
        }
    }
    catch (SqlException ex)
    {
        System.Diagnostics.Debug.WriteLine(ex.Message);
    }

    return JsonConvert.SerializeObject(_dicts, Formatting.None);
}

Which produces the error of:

Error CS0029 Cannot implicitly convert type 'System.Collections.Generic.Dictionary<WCF.Service.NNicsAPI.jsonOutputStyle, System.Collections.Generic.KeyValuePair<string, string>>' to 'System.Collections.Generic.Dictionary<string, string>'

So from that I'm not sure what all I need to do in order to correct the issue so that the json output looks like this:

[{"Name":"","Value":""},{"Name":"Female","Value":"F"},{"Name":"Male","Value":"M"}];

and not like this:

[{"key":"","value":""},{"key":"Female","value":"F"},{"key":"Male","value":"M"}];
StealthRT
  • 10,108
  • 40
  • 183
  • 342
  • `_dicts` has a declared type. You're trying to assign something else to it. The error is telling you the type of the object you are assigning to it. I suggest you declare it as the type of the value you want to assign to it. This is customary: For example, if I want a reference to a string, I declare the variable as `String foo;`. If I want to a reference to a Window, I would declare the variable as `Window foo;`. If I want a refernce to `System.Collections.Generic.Dictionary>`, same principle applies – 15ee8f99-57ff-4f92-890c-b56153 Jun 18 '19 at 15:54
  • 2
    Why are you using `ToDictionary(pair => new jsonOutputStyle(){...})` instead of `ToDictionary(p => p.Key, p => p.Value)`? Your query returns multiples of `KeyValuePair`s right? Since you've declared your dict to accept `string, string` you need a KeySelector and a ValueSelector if you simply want to create a dictionary from those `KeyValuePair`s. – Joelius Jun 18 '19 at 15:59
  • @Joelius I'm doing so because of the title of this question - **rename key/value to Name/Value json.net output** – StealthRT Jun 18 '19 at 16:01
  • Ahh now I understand. I'll add an answer if it wasn't solved until then. – Joelius Jun 18 '19 at 16:03

2 Answers2

2

Try this:

_dicts = Oconn.Query<KeyValuePair<string, string>>(
                            "SELECT " +
                                "POB_CODE AS Key," +
                                "POB_DESC AS Value " +
                            "FROM " +
                                "POB_CODE " +
                            "WHERE " +
                                "DISPLAY_SORT_ORDER >=1 " +
                            "AND " +
                                "DISPLAY_SORT_ORDER <=60",
                            null
                          )
                   .ToDictionary(pair => pair.Key, pair => pair.Value);

I don't understand why you want "Key" to be named as "Name". When a dictionary is converted into JSON it will look like this {"actual_value_of_key" : "value"}. You will not see the variable Name written.

EDIT: if you want JSON output like [{"Name":"","Value":""},{"Name":"Female","Value":"F"},{"Name":"Male","Value":"M"}] then don't use the dictionary. Use your defined class.

_dicts = Oconn.Query<jsonOutputStyle>(
                            "SELECT " +
                                "POB_CODE AS Name," +
                                "POB_DESC AS Value " +
                            "FROM " +
                                "POB_CODE " +
                            "WHERE " +
                                "DISPLAY_SORT_ORDER >=1 " +
                            "AND " +
                                "DISPLAY_SORT_ORDER <=60",
                            null
                          )
                   .ToList();

Edit, corrected SQL

MIKE
  • 1,039
  • 7
  • 24
1

You don't need to convert them when adding them to a dictionary. What you want to do is fill the dictionary like you would always (with a Key- and a Value-selector) and then before serialisation, change it to a list of your Type which then defines how it'll be serialized.

Try it:

[Obsolete]
public string POB_CODE()
{
    Dictionary<string, string> _dicts = null;

    try
    {
        using (OracleConnection Oconn = new OracleConnection(connectionORI))
        {
            _dicts = Oconn.Query<KeyValuePair<string, string>>(
                                "SELECT " +
                                    "POB_CODE AS Key," +
                                    "POB_DESC AS Value " +
                                "FROM " +
                                    "POB_CODE " +
                                "WHERE " +
                                    "DISPLAY_SORT_ORDER >=1 " +
                                "AND " +
                                    "DISPLAY_SORT_ORDER <=60",
                                null
                            )
                    .ToDictionary(p => p.Key, p => p.Value);
        }
    }
    catch (SqlException ex)
    {
        System.Diagnostics.Debug.WriteLine(ex.Message);
    }

    jsonOutputStyle[] styledDictionary = _dicts.Select(p => new jsonOutputStyle() { Name = p.Key, Value = p.Value }).ToArray();
    return JsonConvert.SerializeObject(styledDictionary, Formatting.None);
}

Breakdown of the important changes:

.ToDictionary(p => p.Key, p => p.Value);

instead of

.ToDictionary(pair => new jsonOutputStyle() { 
   Name = pair.Key, 
   Value = pair.Value
});

Here we first need to get a simple dictionary with string as key and string as value. We do this by using two selectors. One for the key (p => p.Key) and one for the value (p => p.Value). We don't need to worry about serializing yet.

Now for serializing we don't directly serialize the dictionary but instead, cast the dictionary to an array of your tupel-type. This allows us to serialize the names you defined in that class and not pre-defined property-names.

jsonOutputStyle[] styledDictionary = _dicts.Select(p => new jsonOutputStyle() { Name = p.Key, Value = p.Value }).ToArray();
return JsonConvert.SerializeObject(styledDictionary, Formatting.None);

Also right here is the answer to a very similar question which essentially does the same thing I just showed you.

Also for anyone wondering what happens when you serialize YourTupel[] vs Dictionary<string, string> vs List<KeyValuePair<string, string>>:

Serialized ArrayOfYourType:
[{"Name":"Key 0","Value":"Value 0"},{"Name":"Key 1","Value":"Value 1"}]

Serialized Dictionary:
{"Key 0":"Value 0","Key 1":"Value 1"}

Serialized List:
[{"Key":"Key 0","Value":"Value 0"},{"Key":"Key 1","Value":"Value 1"}]

EDIT:
I assumed you need the dictionary (for example to check if the keys are distinct or something like this). If you don't need the dictionary at all, you can directly cast the array without ever having to do something with a dictionary.

The code would look like this:
Ps. The edit in this answer uses dapper functionality to make this even cleaner, go check it out.

[Obsolete]
public string POB_CODE()
{
    jsonOutputStyle[] styledDictionary = null;

    try
    {
        using (OracleConnection Oconn = new OracleConnection(connectionORI))
        {
            _dicts = Oconn.Query<KeyValuePair<string, string>>(
                                "SELECT " +
                                    "POB_CODE AS Key," +
                                    "POB_DESC AS Value " +
                                "FROM " +
                                    "POB_CODE " +
                                "WHERE " +
                                    "DISPLAY_SORT_ORDER >=1 " +
                                "AND " +
                                    "DISPLAY_SORT_ORDER <=60",
                                null
                            )
                    .Select(p => new jsonOutputStyle() { Name = p.Key, Value = p.Value }).ToArray();
        }
    }
    catch (SqlException ex)
    {
        System.Diagnostics.Debug.WriteLine(ex.Message);
    }

    return JsonConvert.SerializeObject(styledDictionary, Formatting.None);
}
Joelius
  • 3,839
  • 1
  • 16
  • 36