我正在尝试编写API - 其网站上显示的预期输出(针对第三方)是下面的JSON:
{
"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/
它给了我以下课程:
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”是一个变量 - 所以我不认为它也可以是一个类名。但可能只是因为我不知道如何创建这样的类。
我只是无法弄清楚“芬威室” - 我认为它需要有类似的东西:“房间名称”:“芬威室” - 但也许还有另一种定义类的方法,以便它不会需要一个标签“房间名称”。
我非常感谢您确认是否可以创建与JSON相匹配的类。
谢谢,Mark
答案 0 :(得分: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());
答案 1 :(得分: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框架序列化程序执行此操作,但您需要执行额外的工作。
答案 2 :(得分:0)
尝试添加JsonPropteryAttribute。
public class RoomTypes
{
[JsonProperty(PropertyName="FenWay Room")]
public FenwayRoom room { get; set; }
}
答案 3 :(得分:0)
如果您使用此工具(http://jsonclassgenerator.codeplex.com/),它将生成稍微好一些支持这些属性名称的C#。
//由Xamasoft JSON类生成器生成 // http://www.xamasoft.com/json-class-generator
使用System; 使用System.Collections.Generic; 使用Newtonsoft.Json; 使用Newtonsoft.Json.Linq; 使用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; }
}
}