如何使用WebAPI返回Dictionary <complextype,int>

时间:2015-07-01 22:50:49

标签: c# json xml asp.net-web-api

我提供了以这种方式完成的WebApi 2端点:

我的控制器很简单:

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

MyClass的结构是:

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

当我运行我的网络服务时,帮助程序网页显示预期输出为:

{ "MyNamespace.MyProject.MyClass": 1 }

另一方面,xml样本是我喜欢的(除了我想要json,而不是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 >

我还使用Postman运行了端点,并确认返回的值是WebApi开箱即用的预览值。

为什么json是&#34;错误&#34;并且xml做得很好(我的意思是包含所有数据)?

更新:

我希望MyClass在json中序列化如下:

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

这应该是我的字典的键的结构,因为它在xml表示中。

由于

3 个答案:

答案 0 :(得分:4)

这有点像hacky,但是在通过JsonConvert运行它之前,我将Dictionary转换为List对象取得了成功。看看:

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

然而。 。 。

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

希望有所帮助。

答案 1 :(得分:2)

通常,字典用于生成更多动态JSON对象,方法是将键/值对用作JavaScript对象上的名称/值对。但是JSON对象不能使用另一个JSON对象作为其键。例如,以下语法无效:

{
    {"Property1": "sample string 4",... } : 1,
    {"Property1": "sample string 5",... } : 2,
}

因此,您需要确切地确定如何在JSON中表示此信息。你是否认为它是一个Key / Value对象数组?

[ 
    { Key: {"Property1": "sample string 4",...}, Value: 1 },
    { Key: {"Property1": "sample string 5",...}, Value: 2 },
]

在这种情况下,请通过List<KeyValuePair<string, int>>从您的方法返回dict.ToList()

你的钥匙和价值观有意义吗?也许您应该创建一个类来通过dict.Select(kvp => new MyDto { MyClass = kvp.Key, Foo = kvp.Value }).ToList()

来表示具有自定义属性名称的每个项目
[ 
    { MyClass: {"Property1": "sample string 4",...}, Foo: 1 },
    { MyClass: {"Property1": "sample string 5",...}, Foo: 2 },
]

你想坚持使用对象,但左手边是你班级的字符串表示吗?您可以通过在MyClass上实现ToString()方法来实现此目的:

{ 
    "sample string 4|8|5": 1, 
    "sample string 5|6|7": 2
} 

答案 2 :(得分:1)

您的控制器是什么样的?端点应如下所示:

[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); 
} 

如果您之后仍然遇到JSON序列化问题,则可以在Web API中配置默认​​的JsonFormatter类型:GlobalConfiguration.Configuration.Formatters.JsonFormatter;。有关详细信息,请参阅the ASP.NET Web API Serialization Documentation