2013-10-31 52 views
5

我試圖寫一個API - 在其網站上所示的預期輸出(用於第三方)低於JSON:在ASP.Net轉換JSON到C#類MVC

{ 
"api_version" : 4 , 
"hotel_ids" : [97497], 
"hotels" : 
    [ 
     { 
      "hotel_id": 97497, 
      "room_types": 
       { 
        "Fenway Room": 
         { 
          "url": "someurlhere", 
          "price": 178.50, 
          "room_code": "SINGLE"        
         } 
       } 
     } 
    ] 
} 

http://json2csharp.com/

它給了我下面的類:使用在線工具M

public class FenwayRoom 
{ 
public string url { get; set; } 
public double price { get; set; } 
public string room_code { get; set; } 
} 

public class RoomTypes 
{ 
public FenwayRoom __invalid_name__Fenway Room { get; set; } 
} 

public class Hotel 
{ 
public int hotel_id { get; set; } 
public RoomTypes room_types { get; set; } 
} 

public class RootObject 
{ 
public int api_version { get; set; } 
public List<int> hotel_ids { get; set; } 
public List<Hotel> hotels { get; set; } 
} 

你可以看到RoomTypes:

FenwayRoom __invalid_name__Fenway Room { get; set; }

我在想,如果他們的JSON規範是錯誤的,或者有沒有辦法讓我創建類來返回他們期待的JSON?

在這個例子中,我認爲房型「Fenway Room」是一個變量 - 所以我不認爲它也可以是類名。但可能只是我不知道如何創建這樣的課程。

我只是無法弄清楚「Fenway房間」 - 我認爲需要這樣的房間:「房間名稱」:「Fenway房間」 - 但也許有另一種定義類的方法,以便它不會不需要標籤「房間名稱」。

我很感激任何幫助確認是否有可能創建類來匹配他們的JSON。

謝謝,馬克

+0

你嘗試'JavaScriptSerializer'?它有一個通用的方法來轉換 這裏是檢查出 鏈接http://msdn.microsoft.com/en-us/library/bb355316.aspx –

+2

的問題似乎是「芬威房」具有它的空間 - 因此該工具無法自動爲其生成映射,因爲標識符中不允許使用空格。所以你可能不得不使用一些不依賴直接標識符映射的自定義序列化技術。當然,如果供應商可以修改他們的飼料,以刪除空間,所有更好 –

+0

嗨亞歷克斯 - 不,那是什麼?我必須創建該對象以返回我的MVC C#代碼 - 並且該對象必須返回上面首先粘貼的示例代碼。我只是無法弄清楚「Fenway Room」 - 我認爲它需要這樣的內容:「Room Name」:「Fenway Room」 - 但也許還有另一種定義類的方法,以便它不需要標籤「房間名稱」。謝謝,Mark – Mark

回答

1

當使用JSON。NET的輸出

"room_types": 
{ 
    "Fenway Room": 
    { 
     "url": "someurlhere", 
     "price": 178.50, 
     "room_code": "SINGLE"        
     } 
    } 
} 

看看你會得到什麼序列化字典。

類改爲

public class Room 
{ 
    public string url { get; set; } 
    public double price { get; set; } 
    public string room_code { get; set; } 
} 

public class Hotel 
{ 
    public int hotel_id { get; set; } 
    public Dictionary<string, Room> room_types { get; set; } 
} 

public class RootObject 
{ 
    public int api_version { get; set; } 
    public List<int> hotel_ids { get; set; } 
    public List<Hotel> hotels { get; set; } 
} 

這是所有預測使用Json.NET,它給你以這種形式爲免費詞典的這種序列化/反序列化。您可以使用.NET框架序列化程序執行此操作,但您需要做額外的工作。

0

嘗試添加JsonPropteryAttribute。

public class RoomTypes 
{ 
    [JsonProperty(PropertyName="FenWay Room")] 
    public FenwayRoom room { get; set; } 
} 
0

如果您使用此工具(http://jsonclassgenerator.codeplex.com/),它會生成稍微好一點的C#,以支持這些屬性名稱。

//使用系統由Xamasoft JSON類生成 // http://www.xamasoft.com/json-class-generator

生成的; using System.Collections.Generic; 使用Newtonsoft.Json; 使用Newtonsoft.Json.Linq; using Example.SampleResponse1JsonTypes;

namespace Example.SampleResponse1JsonTypes 
{ 

    internal class FenwayRoom 
    { 

     [JsonProperty("url")] 
     public string Url { get; set; } 

     [JsonProperty("price")] 
     public double Price { get; set; } 

     [JsonProperty("room_code")] 
     public string RoomCode { get; set; } 
    } 

    internal class RoomTypes 
    { 

     [JsonProperty("Fenway Room")] 
     public FenwayRoom FenwayRoom { get; set; } 
    } 

    internal class Hotel 
    { 

     [JsonProperty("hotel_id")] 
     public int HotelId { get; set; } 

     [JsonProperty("room_types")] 
     public RoomTypes RoomTypes { get; set; } 
    } 

} 

namespace Example 
{ 

    internal class SampleResponse1 
    { 

     [JsonProperty("api_version")] 
     public int ApiVersion { get; set; } 

     [JsonProperty("hotel_ids")] 
     public int[] HotelIds { get; set; } 

     [JsonProperty("hotels")] 
     public Hotel[] Hotels { get; set; } 
    } 

} 
+0

嗨 - 抱歉,我不認爲我是putti正確地穿過它。 「FenwayRoom」是一個房間名稱,而不是一個類 - 所以如果我有50個不同的房間,我不認爲我可以在Visual Studio中動態創建C#代碼中的類。我相信* *「FenwayRoom」應爲「ROOMNAME」:「FenwayRoom」 - 但我不知道是否有一個默認的屬性,因此「FenwayRoom」不需要「ROOMNAME」這樣我就可以返回JSON API被期待。謝謝,馬克 – Mark

+0

對於RoomType對象,在API中描述說:room_types使用的簡短描述的關鍵和可用性房型對象作爲價值 地圖。 - 那麼如何將一個動態名稱作爲C#類中的一個鍵?也許我剛剛問過這個問題 - 我會再次發佈 - 謝謝大家的幫助。 – Mark

1

改變你的類的結構如下:

public class Rootobject 
{ 
    public int api_version { get; set; } 
    public List<int> hotel_ids { get; set; } 
    public List<Hotel> hotels { get; set; } 
} 

public class Hotel 
{ 
    public int hotel_id { get; set; } 
    public Room_Types room_types { get; set; } 
} 

public class Room_Types 
{ 
    public List<Room> Rooms { get; set; } 
} 

public class Room 
{ 
    public string Type { get; set; } 
    public string Url { get; set; } 
    public float Price { get; set; } 
} 

創建下面的類,它實現了JsonConverter抽象類:

public abstract class MyJsonConverter<T> : JsonConverter 
{ 
    protected abstract T Create(Type objectType, JObject jObject); 

    public override bool CanConvert(Type objectType) 
    { 
     return typeof(T).IsAssignableFrom(objectType); 
    } 

    public override object ReadJson 
     (JsonReader reader, 
     Type objectType, 
     object existingValue, 
     JsonSerializer serializer) 
    { 
     JObject jObject = JObject.Load(reader); 
     T target = Create(objectType, jObject); 
     serializer.Populate(jObject.CreateReader(), target); 
     return target; 
    } 

    public override void WriteJson 
     (JsonWriter writer, 
     object value, 
     JsonSerializer serializer) 
    { 
     // 
    } 
} 

按以下步驟實現MyJsonConverter<T>類:

public class RoomConverter : MyJsonConverter<Room_Types> 
{ 
    protected override Room_Types Create(Type objectType, JObject jObject) 
    { 
     var rooms = jObject.Cast<JToken>().Select(t => new Room 
     { 
      Type = ((JProperty)t).Name, 
      Url = ((JProperty)t).First 
       .SelectToken("url").ToString(), 
      Price = float.Parse(((JProperty)t).First 
       .SelectToken("price").ToString()) 
     }).ToList(); 
     return new Room_Types() { Rooms = rooms }; 
    } 
    public override void WriteJson 
     (JsonWriter writer, 
     object value, 
     JsonSerializer serializer) 
    { 
     writer.WriteStartObject(); 
     ((Room_Types)value).Rooms.ForEach(r => 
     { 
      writer.WritePropertyName(r.Type); 
      writer.WriteStartObject(); 
      writer.WritePropertyName("url"); 
      writer.WriteValue(r.Url); 
      writer.WritePropertyName("price"); 
      writer.WriteValue(r.Price); 
      writer.WriteEndObject(); 
     }); 
     writer.WriteEndObject(); 
    } 
} 

現在你可以反序列化/序列化是這樣的:

var result = JsonConvert 
    .DeserializeObject<Rootobject>(jsonText, new RoomConverter()); 
var serialized = JsonConvert 
    .SerializeObject(result, new RoomConverter());