如何从 WCF REST 方法将自定义类型值的字典作为常规 JSON 对象返回?

问题描述 投票:0回答:1

假设我有一个如下所示的自定义类型:

[DataContract]
public class CompositeType
{
    [DataMember]
    public bool HasPaid
    {
        get;
        set;
    }

    [DataMember]
    public string Owner
    {
        get;
        set;
    }
}

还有一个 WCF REST 接口,如下所示:

[ServiceContract]
public interface IService1
{
    [OperationContract]
    Dictionary<string, CompositeType> GetDict();
}

那么我如何实现该方法以返回如下所示的 JSON 对象...

{"fred":{"HasPaid":false,"Owner":"Fred Millhouse"},"joe":{"HasPaid":false,"Owner":"Joe McWirter"},"bob":{"HasPaid":true,"Owner":"Bob Smith"}}

我确实希望它看起来像这样:

[{"Key":"fred","Value":{"HasPaid":false,"Owner":"Fred Millhouse"}},{"Key":"joe","Value":{"HasPaid":false,"Owner":"Joe McWirter"}},{"Key":"bob","Value":{"HasPaid":true,"Owner":"Bob Smith"}}]

理想情况下,我宁愿不必更改方法的返回类型。

我尝试了许多不同的方法,但找不到有效的解决方案。令人烦恼的是,用

Newtonsoft.Json
:

很容易在一行中生成正确形状的 JSON 对象结构
string json = JsonConvert.SerializeObject(dict);

其中

dict
定义为:

Dictionary<string, CompositeType> dict = new Dictionary<string, CompositeType>();
dict.Add("fred", new CompositeType { HasPaid = false, Owner = "Fred Millhouse" });
dict.Add("joe", new CompositeType { HasPaid = false, Owner = "Joe McWirter" });
dict.Add("bob", new CompositeType { HasPaid = true, Owner = "Bob Smith" });

但我不想从 WCF 方法返回字符串。这是因为它隐藏了返回的真实类型;而且因为 WCF 也会序列化字符串,导致转义双引号和其他丑陋的内容,使非 .Net REST 客户端更难解析。

c# json wcf rest
1个回答
5
投票

这是回应@dbc 评论的部分解决方案。它产生了这个正确形状的 JSON 结构...

{"fred":{"HasPaid":false,"Owner":"Fred Millhouse"},"joe":{"HasPaid":false,"Owner":"Joe McWirter"},"bob":{"HasPaid":true,"Owner":"Bob Smith"}}

但不幸的是,必须将方法的返回类型更改为

Message
。界面变成:

[ServiceContract]
public interface IService1
{
    [OperationContract]
    Message GetDict();
}

实现变为:

using Newtonsoft.Json;
using System.ServiceModel.Channels;
...
[WebGet(ResponseFormat = WebMessageFormat.Json)]
public Message GetDict()
{
    Dictionary<string, CompositeType> dict = new Dictionary<string, CompositeType>();
    dict.Add("fred", new CompositeType { HasPaid = false, Owner = "Fred Millhouse" });
    dict.Add("joe", new CompositeType { HasPaid = false, Owner = "Joe McWirter" });
    dict.Add("bob", new CompositeType { HasPaid = true, Owner = "Bob Smith" });

    string json = JsonConvert.SerializeObject(dict);
    return WebOperationContext.Current.CreateTextResponse(json, "application/json; charset=utf-8", Encoding.UTF8);
}

需要注意的一个有用功能是,与返回

Stream
不同,当您访问 REST 方法的 URI 时,您可以轻松地在 Web 浏览器中查看 JSON。

© www.soinside.com 2019 - 2024. All rights reserved.