Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return Dictionary<complexType,int> with WebAPI

I'm providing a WebApi 2 endpoint that is done in this way:

My controller is simply:

 public IDictionary<MyClass, int> GetMyClasses(string id)
 {
    Dictionary<MyClasses, int> sample = new Dictionary<MyClasses, int>();

    sample.Add(new MyClasses()
    {
       Property1 = "aaa",
       Property2 = 5,
       Property3 = 8
    },10);

    return sample;
 }

The structure of MyClass is:

public class MyClass
{
   string Property1 {get;set;}
   int Property2 {get;set;}
   int Property3 {get;set;}
}

When I run my webservice, the helper webpage shows me that the expected outputs are:

{ "MyNamespace.MyProject.MyClass": 1 }

On the other hand the xml sample is what I'd like (except that I want the json, not the xml):

<ArrayOfKeyValueOfMyClassintl85fHlC_P xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
  <KeyValueOfMyClassintl85fHlC_P>
    <Key xmlns:d3p1="http://schemas.datacontract.org/2004/07/MyNamespace.MyProject.MyClass">
      <d3p1:Property1>sample string 4</d3p1:Property1>
      <d3p1:Property2>8</d3p1:Property2>
      <d3p1:Property3>5</d3p1:Property3>
    </Key>
    <Value>1</Value>
  </KeyValueOfMyClassintl85fHlC_P>
</ArrayOfKeyValueOfMyClassintl85fHlC_P >

I also ran the endpoint with Postman and it confirms that the returned value is the one previewed by the WebApi out of the box page.

Why the json is "wrong" and the xml is well done (I mean that contains all the data)?

UPDATED:

I expected MyClass serialized in json like this:

{
  "Property1": "sample string 4",
  "Property2": 8,
  "Property3": 5
}

This should be the structure of the key of my dictionary, as it is in the xml representation.

Thanks

like image 373
ff8mania Avatar asked Jul 01 '15 22:07

ff8mania


2 Answers

This is kind of hacky, but I had success by converting the Dictionary to a List object before running it through JsonConvert. Check it out:

IDictionary<MyClass,int> dict = new Dictionary<MyClass, int>();
MyClass classy = new MyClass() { value = value };
dict.Add(classy, 5);
string json = JsonConvert.SerializeObject(dict); //<--- Returns [{MyClass: 5}], boo

Whereas . . .

string json = JsonConvert.SerializeObject(dict.ToList()); //<--- Returns [{Key: blah blah blah, Value: 5}], nice

Hope that helps.

like image 75
codeMonkey Avatar answered Sep 23 '22 14:09

codeMonkey


What does your Controller look like? The endpoint should look something like this:

[Route("")] 
public IHttpActionResult Get() 
{ 
    IDictionary<MyClass, int> resource = new Dictionary<MyClass, int> 
    {
        { new MyClass {Property1="1", Property2=2, Property3=3}, 0 },
        { new MyClass {Property1="11", Property2=22, Property3=33}, 1 },
    };

    return Ok(resource); 
} 

If you're still having JSON serialization issues after that, you can configure the default JsonFormatter type in Web API: GlobalConfiguration.Configuration.Formatters.JsonFormatter;. See the ASP.NET Web API Serialization Documentation for more information.

like image 22
Ryan Erdmann Avatar answered Sep 20 '22 14:09

Ryan Erdmann