Here's my dilemma. I'm using a RESTful ASP.NET service, trying to get a function to return a JSON string in this format:
{"Test1Key":"Test1Value","Test2Key":"Test2Value","Test3Key":"Test3Value"}
But I'm getting it in this format instead:
[{"Key":"Test1Key","Value":"Test1Value"}, {"Key":"Test2Key","Value":"Test2Value"}, {"Key":"Test3Key","Value":"Test3Value"}]
My method looks like this:
[OperationContract] [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)] public Dictionary<string, string> Test(String Token) { if (!IsAuthorized(Token)) return null; if (!IsSecure(HttpContext.Current)) return null; Dictionary<string, string> testresults = new Dictionary<string, string>(); testresults.Add("Test1Key", "Test1Value"); testresults.Add("Test2Key", "Test2Value"); testresults.Add("Test3Key", "Test3Value"); return testresults; }
Is there any way I can get rid of those "Key" and "Value" tags using only built in ASP.NET tools? (i.e., I'd rather not use JSON.NET, if it's avoidable)
Thanks very much! :)
The .NET dictionary class won't serialize any other way than the way you described. But if you create your own class and wrap the dictionary class then you can override the serializing/deserializing methods and be able to do what you want. See example below and pay attention to the "GetObjectData" method.
[Serializable] public class AjaxDictionary<TKey, TValue> : ISerializable { private Dictionary<TKey, TValue> _Dictionary; public AjaxDictionary() { _Dictionary = new Dictionary<TKey, TValue>(); } public AjaxDictionary( SerializationInfo info, StreamingContext context ) { _Dictionary = new Dictionary<TKey, TValue>(); } public TValue this[TKey key] { get { return _Dictionary[key]; } set { _Dictionary[key] = value; } } public void Add(TKey key, TValue value) { _Dictionary.Add(key, value); } public void GetObjectData( SerializationInfo info, StreamingContext context ) { foreach( TKey key in _Dictionary.Keys ) info.AddValue( key.ToString(), _Dictionary[key] ); } }
Expanding slightly on @MarkisT's excellent solution, you can modify the serialization constructor to recreate one of these dictionaries from the same JSON (thus allowing you to take an AjaxDictionary as a service parameter), as follows:
public AjaxDictionary( SerializationInfo info, StreamingContext context ) { _Dictionary = new Dictionary<TKey, TValue>(); foreach (SerializationEntry kvp in info) { _Dictionary.Add((TKey)Convert.ChangeType(kvp.Name, typeof(TKey)), (TValue)Convert.ChangeType(kvp.Value, typeof(TValue))); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With