Serialize ListKeyValuePairstring, string as JSON
You can use Newtonsoft and dictionary:
var dict = new Dictionary<int, string>();
dict.Add(1, "one");
dict.Add(2, "two");
var output = Newtonsoft.Json.JsonConvert.SerializeObject(dict);
The output is :
{"1":"one","2":"two"}
Edit
Thanks to @Sergey Berezovskiy for the information.
You are currently using Newtonsoft, so just change your List<KeyValuePair<object, object>>
to Dictionary<object,object>
and use the serialize and deserialize method from the package.
JSON Serialize ListKeyValuePairstring, object
If you use the Newtonsoft Json.NET library you can do the following.
Define a converter to write the list of key/value pairs the way you want:
class MyConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
List<KeyValuePair<string, object>> list = value as List<KeyValuePair<string, object>>;
writer.WriteStartArray();
foreach (var item in list)
{
writer.WriteStartObject();
writer.WritePropertyName(item.Key);
writer.WriteValue(item.Value);
writer.WriteEndObject();
}
writer.WriteEndArray();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
// TODO...
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(List<KeyValuePair<string, object>>);
}
}
Then use the converter:
var keyValuePairs = new List<KeyValuePair<string, object>>
{
new KeyValuePair<string, object>("one", 1),
new KeyValuePair<string, object>("two", 2),
new KeyValuePair<string, object>("three", 3)
};
JsonSerializerSettings settings = new JsonSerializerSettings { Converters = new [] {new MyConverter()} };
string json = JsonConvert.SerializeObject(keyValuePairs, settings);
This generates [{"one":1},{"two":2},{"three":3}]
How to deserialize JSON to IListKeyValuePairstring, object with whitespaces in key?
You can't use IList
or List
here, because your source JSON has no [ ]
in it, which is a requirement if you want to parse into such a collection. In other words, without [ ]
you can't parse into a collection, at least not without going through lots of hoops.
Instead you need to use a Dictionary as was suggested already in comments.
Note: I used Newtonsoft JsonConvert because you didn't state what your parser is, but that should make little or no difference to my arguments.
Working code:
var json = "{ \"spec\": { \"SOMETHING WITH SPACES\" : \"10\" } }";
var someObj = JsonConvert.DeserializeObject<SomeObject>(json);
public class SomeObject
{
public Dictionary<string, object> spec{ get; set; }
}
After that, you can cast the spec
property to an IEnumerable
and loop through whatever was found:
foreach (var pair in someObj.spec as IEnumerable<KeyValuePair<string, object>>)
{
Console.WriteLine(pair.Key + " -> " + pair.Value);
}
Or even convert it to a List:
var list = someObj.spec.ToList();
foreach (var pair in list)
{
Console.WriteLine(pair.Key + " -> " + pair.Value);
}
.NET Fiddle: https://dotnetfiddle.net/15l2R3
Serialize a ListKeyValuePairstring, object
Given your requirement not to implement IXmlSerializable
, you could add a public XElement[]
surrogate property marked with [XmlAnyElement]
to your type:
[XmlIgnore]
public List<KeyValuePair<string, object>> Items { get; set; }
[XmlAnyElement]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DebuggerBrowsable(DebuggerBrowsableState.Never)]
public XElement[] XmlItems
{
get
{
if (Items == null)
return null;
return Items.Select(p => new XElement(p.Key, (p.Value ?? string.Empty).ToString())).ToArray();
}
set
{
if (value == null)
return;
Items = Items ?? new List<KeyValuePair<string, object>>(value.Length);
foreach (var e in value)
{
Items.Add(new KeyValuePair<string, object>(e.Name.LocalName, e.Value));
}
}
}
The original property is marked with [XmlIgnore]
while the surrogate property returns an array of XElement
objects whose names are mapped from KeyValuePair.Key
and whose values are mapped from KeyValuePair.Value.ToString()
.
Sample fiddle.
Cannot deserialize Json file to a list of KeyValuePair with string key
As mentioned in a comment above, the solution is to use a list of dictionary. (not just a dictionary and not a list of KeyValuePair)
List<Dictionary<string, SpellCheckSuggestion>>
How to deserialize JSON into a ListKeyValuePairstring,string set
From what I can see it should not be possible using the JavaScriptSerializer. The only way for customizing its behavior is by means of a JavaScriptConverter class, that will allow you to customize the serialization/deserialization process. Unfortunately both methods will pass an IDictionary for the properties, therefore the duplicated names are already merged. You might want to look into either a different format for your JSON or a different serialization library such as JSON.net which is way more customizable.
Serialize list of Name Value pairs with excluding the Key and Value parts
To get the output you want, Components
needs to be a Dictionary<string, string>
rather than a List<KeyValuePair<string, string>>
. So the simplest solution is to change your class to that effect:
public class Incident
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("components")]
public Dictionary<string, string> Components { get; set; }
public Incident()
{
Components = new Dictionary<string, string>();
}
}
Fiddle: https://dotnetfiddle.net/Mx4Z8U
Of course, the drawback to this solution is that you now have to update all the code which uses Incident
to work with a Dictionary
rather than a List
. Depending on how many dependencies there are, you may or may not want to do that.
So, the second simplest solution is to create a surrogate Dictionary<string, string>
property in the class which uses the List<KeyValuePair<string, string>>
as its source of data. It can be private if you like. Move the [JsonProperty("components")]
attribute to the new Dictionary
and mark the List<KeyValuePair<string, string>>
with [JsonIgnore]
instead. So you would have this:
public class Incident
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonIgnore]
public List<KeyValuePair<string, string>> Components { get; set; }
[JsonProperty("components")]
private Dictionary<string, string> ComponentDictionary
{
get { return Components != null ? new Dictionary<string, string>(Components) : null; }
}
public Incident()
{
Components = new List<KeyValuePair<string, string>>();
}
}
Fiddle: https://dotnetfiddle.net/Po22Yt
Related Topics
How to Detect Iis Version Using C#
Changing a C# Delegate's Calling Convention to Cdecl
Bind 5 Items in Each Row of Repeater
Why Accessviolationexception Cannot Be Caught by .Net4.0
HTML5 Email Input Cannot Assign Id and Runat="Server" ASP.NET 4
Soap Authentication Fails When Running a C# App on a Linux Box
Parsing a Auto-Generated .Net Date Object with JavaScript/Jquery
Using C# 6 Features with Codedomprovider (Roslyn)
Directory.Getcurrentdirectory() Not Working on Linux
Update Float Array from C++ Native Plugin
Search Xdocument Using Linq Without Knowing the Namespace
How to Return Dynamic Object from SQL Query
HTMLagilitypack HTMLweb.Load Returning Empty Document
How to Call a Function of a C++ Dll That Accepts a Parameter of Type Stringstream from C#