2017-02-20 54 views
1

我构建了一个WCF web API(.Net 4.5),它响应来自http://localhost:62633/returnsdesk 的GET并返回一个json列表。WCF返回的json列表也需要列表的名称

[{ “名称”: “拒绝”, “状态”: “FULL”},{ “名称”: “返回”, “状态”: “OK”}]

然而要更好地格式化JSON的样子:

{ “目的地”: [{ “destinationName”: “拒绝”, “状态”: “FULL”},{ “destinationName”: “StevesDesk”,”状态“:”OK“}] }

我不知道如何谷歌这一点。

如何获取WCF到WebGet & WebMessageFormat.Json来命名json列表?

+1

标题与您的问题有何关系? – wkl

+0

你对问题的名称是正确的。我现在就解决这个问题。不知道从哪里来。谢谢。 – Steve

+1

@愿意不需要手工编辑。 '[{“Name”:“reject”,“status”:“FULL”},{“Name”:“returns”,“status”:“OK”}]'是WCF返回的字符串。逐字节。但问题是没有包含列表的名称。 – Steve

回答

0

这真的属于@ user18925 38

取正被串行化并以列表(List<Desk>)由WCF返回的类型,敷在另一种类型的,例如:

[DataContract] 
    public class retDesks { [DataMember] public List<Desk> destinations; } 

现在WCF返回所需的名称:

{“destinations”: [{“ID”:1,“destinationName”:“reject”,“status”:“FULL”},{“ID”:2, “destinationName”:“StevesDesk”,“status “:”OK“}]}

但是您还会注意到Json Desk对象现在还包含属性ID。由于ID未被[DataMember]修饰,所以ID被输出中的Desk的定义隐藏起来。

然而,Desk上的装饰并不重要,因为整个Desk类型在retDesks[DataMember] List<Desk>的情况下被暴露。

那么你如何处理? 最喜欢快速的建议,使用LINQ筛选出List<Desks>的属性,如:

var d1 = _desks.Select(e => new { e.destinationName, e.status }); 

坏消息这里是d1是一个匿名类型的列表。 这是包含List<Desks>retDesks类型的定义所不能接受的。

因此...创建第三个类型public deskRet [ public string destinationName; public string status; }并将此类型设置为Linq输出和返回类型retDesks的实例之间的列表。

public class Desk { public int ID; public string destinationName; public string status; } 

public class retDesks { [DataMember] public List<deskRet> destinations; } 

public class deskRet { public string destinationName; public string status; } 

... 

List<deskRet> d1 = _desks.Select(e => 
    new deskRet{ destinationName=e.destinationName, status=e.status } 
    ).ToList<deskRet>(); // maybe I'm working to hard to guarantee the type. But I'm okay with that 
return(new retDesks{ destinations=d1 }; 

在你有spec'ed输出的一天结束:

{ “目的地”:[{ “destinationName”: “拒绝”, “状态”: “FULL”} { “destinationName”: “StevesDesk”, “状态”: “OK”}]}

不过下次考虑像Json.NET第三方框架。或者,也许只有使用.Net WCF框架的定制Json串行器。

2

我假设你有一个方法,饰以

[WebInvoke(Method = "GET", 
     RequestFormat = WebMessageFormat.Json, 
     ResponseFormat = WebMessageFormat.Json, 
     UriTemplate = "returnsDesk")] 
[WebGet(ResponseFormat = WebMessageFormat.Json)] 

返回List<Desk>

public List<Desk> GetDesks() 
{ 

你需要返回一个新的类DeskList[DataMember]装饰destinations属性,定义为List<Desk>,含有这样的列表,来代替。

+0

你所有的假设都是正确的。这是一个GET。我甚至尝试了'\t \t [return:MessageParameter(Name =“balbal”)]'装饰(没有在这里工作,但我希望它做到了。以编程方式定制这个属性的能力会很好)。剩下的你所说的话是有道理的,我会稍后再尝试,并在这里回到你身边。不知何故,我只是觉得,这只是发生在列表无论如何,并惊讶地发现它不是。 – Steve

+1

@ user1892539像魅力一样工作,但有一件事,也许你有一个提示。我的内部类“Desk”具有不具有[DataMember]装饰的json之前未公开的属性。当然,即使'Desk'类本身仍然只有'destinationName'和'status'装饰有[DataMember],所有这些属性都被包含在json输出中。我诚实地没有看到这一个来临。 – Steve

+0

看起来像你问这[问题](http://stackoverflow.com/questions/27092802/serialize-object-into-json-but-only-include-properties-with-the-datamember-att),aren你呢? – 2017-02-20 23:22:47

0

学分为LongNameContractResolverBryon Rogers

嗨,你可以使用NewtonSoft。JSON参考序列化和反序列化对象


看看下面的代码来回答你的问题

using Newtonsoft.Json; 
using Newtonsoft.Json.Serialization; 
using System; 
using System.Collections.Generic; 

namespace JsonNamedList 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      //Destinations object 
      var destinations = MockGetDestinations(); 
      //Destinations object as Json string, use the LongNameContractResolver to ignore the Json Property Name 
      var strDestinationsJson = LongNameContractResolver.Serialize(destinations, true); 
      //Print the destinations Json to output 
      Console.WriteLine(strDestinationsJson); 
      //Stop closing the console window 
      Console.ReadKey(); 
     } 

     static Destinations MockGetDestinations() 
     { 
      //[{"Name":"reject","status":"FULL"},{"Name":"returns","status":"OK"}] 
      var apiResponse = "[{'Name':'reject','status':'FULL'},{ 'Name':'returns','status':'OK'}]".Replace("'", "\""); 
      var wrappedApiResponse = WrapIntoDestinations(apiResponse); 
      //destinations as object 
      var destinations = JsonConvert.DeserializeObject<Destinations>(wrappedApiResponse); 

      return destinations; 
     } 

     static string WrapIntoDestinations(string apiResponse) => $"{{'destinations': {apiResponse} }}".Replace("'", "\""); 
    } 

    public class Destination 
    { 
     [JsonProperty(PropertyName = "Name")] 
     public string destinationName { get; set; } 

     [JsonProperty(PropertyName = "status")] 
     public string status { get; set; } 
    } 
    public class Destinations 
    { 
     [JsonProperty(PropertyName = "destinations")] 
     public IEnumerable<Destination> destinations { get; set; } 
    } 
    public class LongNameContractResolver : DefaultContractResolver 
    { 
     protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) 
     { 
      // Let the base class create all the JsonProperties 
      // using the short names 
      IList<JsonProperty> list = base.CreateProperties(type, memberSerialization); 

      // Now inspect each property and replace the 
      // short name with the real property name 
      foreach (JsonProperty prop in list) 
      { 
       prop.PropertyName = prop.UnderlyingName; 
      } 

      return list; 
     } 
     public static string Serialize(object obj, bool useLongNames) 
     { 
      JsonSerializerSettings settings = new JsonSerializerSettings(); 
      settings.Formatting = Formatting.Indented; 
      if (useLongNames) 
      { 
       settings.ContractResolver = new LongNameContractResolver(); 
      } 

      return JsonConvert.SerializeObject(obj, settings); 
     } 
    } 
} 

这将产生以下输出(JSON字符串) enter image description here