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

Posted

技术标签:

【中文标题】如何使用 WebAPI 返回 Dictionary<complexType,int>【英文标题】:How to return Dictionary<complexType,int> with WebAPI 【发布时间】:2015-09-19 07:09:30 【问题描述】:

我正在提供以这种方式完成的 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 是“错误的”而 xml 做得很好(我的意思是包含所有数据)?

更新:

我希望 MyClass 像这样在 json 中序列化:


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

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

谢谢

【问题讨论】:

您希望这会产生什么样的 JSON? 您阐明了您期望 MyClass 如何被序列化,但您如何期望 IDictionary&lt;MyClass,int&gt; 被序列化? @StriplingWarrior 我写的序列化而不是“MyNamespace.MyProject.MyClass”。你认为它会损坏 json 吗? WebApi 2 uses Json.NET as its JSON formatter。默认情况下 Json.NET can only serialize a dictionary whose keys can be converted to a string。请参阅此处了解解决方法:***.com/questions/27332723/… @ff8mania:我希望你能澄清你想要返回值的样子,这样我就可以提供你正在寻找的答案,而不是三个单独的答案和解释你会在什么情况下使用它们。如果你花点时间写出你设想的整个 JSON 对象,你会为我节省很多时间。 【参考方案1】:

这有点 hacky,但我成功地将 Dictionary 转换为 List 对象,然后再通过 JsonConvert 运行它。看看吧:

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

希望对您有所帮助。

【讨论】:

【参考方案2】:

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

[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 了解更多信息。

【讨论】:

【参考方案3】:

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


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

因此,您需要确切地确定您希望如何在 JSON 中表示此信息。您是否将其视为一组键/值对象?

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

在这种情况下,请通过 dict.ToList() 从您的方法中返回 List&lt;KeyValuePair&lt;string, int&gt;&gt;

你的键和值是否有意义?也许你应该创建一个类来用自定义属性名称来表示每个项目,通过dict.Select(kvp =&gt; 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
 

【讨论】:

以上是关于如何使用 WebAPI 返回 Dictionary<complexType,int>的主要内容,如果未能解决你的问题,请参考以下文章

使用 EF 和 WebAPI,如何返回 ViewModel 并支持 IQueryable/OData? [复制]

使用 C# 返回具有重复键的 Json 对象

.NET Dictionary 实现如何与可变对象一起使用

使用多个键调用 Service Fabric Reliable Dictionary

如何修复 webAPI 中不正确的操作路由

如何在 Ocelot 和 .Net WebApi 中覆盖 AuthorizationMiddleware 时返回未经授权的响应