Is There a Serializable Generic Key/Value Pair Class in .Net

Is there a serializable generic Key/Value pair class in .NET?

Just define a struct/class.

[Serializable]
public struct KeyValuePair<K,V>
{
public K Key {get;set;}
public V Value {get;set;}
}

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}]

What is the correct syntax to PUT serialize angular KeyValue to ASP.NET KeyValuePair?

I was able to solve the Issue by creating my own KeyValue Class like so:

public class KeyValue<K,V>
{
public K Key { get; set; }
public V Value { get; set; }
}

after this my Controller Method now looks like this:

[HttpPut("[action]")]
public ActionResult<bool> Sort([FromBody] IList<KeyValue<int, int>> dto)
{
return Ok(_aboutUsService.Sort(dto));
}

Thanks to this approach the Controller was able to receive the sent Array of KeyValue over PUT from Angular to my Webserver...Sample Image

How to serialize an object collection / dictionary into keyvalue/key

This is hard to answer as you don't really clarify what 'best' means to you.

Fastest would probably be the raw write out as strings:

var sb = new StringBuilder();
sb.Append("<identifiers>");
foreach(var pair in identifiers)
{
sb.AppendFormat("<{0}>{1}</{0}>", pair.Key, pair.Value);
}
sb.Append("</identifiers>");

Obviously that's not handling any escaping to XML, but then that might not be a problem, it depends entirely on the contents of your dictionary.

What about fewest lines of code? If that's your requirement then L.B.'s Linq to XML answer's probably best.

What about smallest memory footprint? There I'd look at dropping the Dictionary and creating your own serialisable class that drops the hash overhead and collection functionality in favour of just storing name and value. That might be fastest too.

If code simplicity is your requirement then how about using dynamic or anonymous types instead of Dictionary?

var anonType = new
{
somename = "somedescription",
anothername = "anotherdescription"
}

// Strongly typed at compile time
anonType.anothername = "new value";

That way you're not dealing with 'magic strings' for the names of properties in your collection - it will be strongly typed in your code (if that's important for you).

However anonymous types don't have a built in serialiser - you'd have to write something for yourself, use one of the many open source alternatives or even use the XmlMediaTypeFormatter.

There are loads of ways to do this, which one is best depends on how you're going to use it.

Generic Key/Value pair collection in that preserves insertion order?

There is not. However, System.Collections.Specialized.OrderedDictionary should solve most need for it.

EDIT: Another option is to turn this into a Generic. I haven't tested it but it compiles (C# 6) and should work. However, it will still have the same limitations that Ondrej Petrzilka mentions in comments below.

    public class OrderdDictionary<T, K>
{
public OrderedDictionary UnderlyingCollection { get; } = new OrderedDictionary();

public K this[T key]
{
get
{
return (K)UnderlyingCollection[key];
}
set
{
UnderlyingCollection[key] = value;
}
}

public K this[int index]
{
get
{
return (K)UnderlyingCollection[index];
}
set
{
UnderlyingCollection[index] = value;
}
}
public ICollection<T> Keys => UnderlyingCollection.Keys.OfType<T>().ToList();
public ICollection<K> Values => UnderlyingCollection.Values.OfType<K>().ToList();
public bool IsReadOnly => UnderlyingCollection.IsReadOnly;
public int Count => UnderlyingCollection.Count;
public IDictionaryEnumerator GetEnumerator() => UnderlyingCollection.GetEnumerator();
public void Insert(int index, T key, K value) => UnderlyingCollection.Insert(index, key, value);
public void RemoveAt(int index) => UnderlyingCollection.RemoveAt(index);
public bool Contains(T key) => UnderlyingCollection.Contains(key);
public void Add(T key, K value) => UnderlyingCollection.Add(key, value);
public void Clear() => UnderlyingCollection.Clear();
public void Remove(T key) => UnderlyingCollection.Remove(key);
public void CopyTo(Array array, int index) => UnderlyingCollection.CopyTo(array, index);
}

Serialize dictionary as array (of key value pairs)

Ah, it turns out this is as straightforward as I'd hoped. My Dictionary<k,v> is subclassed already and I found that I can annotate it with [JsonArrayAttribute]. That gives me exactly the format I need;

"MyDict": [
{
"Key": "Apples",
"Value": {
"Taste": 1341181398,
"Title": "Granny Smith",
}
},
{
"Key:": "Oranges",
"Value:": {
"Taste": 9999999999,
"Title": "Coxes Pippin",
}
},
]


Related Topics



Leave a reply



Submit