2017-02-20 51 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