无法反序列化 JSON 内容

Posted

技术标签:

【中文标题】无法反序列化 JSON 内容【英文标题】:Unable to deserialize JSON content 【发布时间】:2014-09-05 06:11:06 【问题描述】:

我在堆栈溢出中看到了很多类似的问题。然而,这并没有多大帮助。我在反序列化我的 JSON 时遇到问题。详情如下:

JSON 内容

    
  "TicketDetails": 

    "General": 
      "TicketingCity": "DEL",
      "ContactNumber": "4567576574",
      "Email": "XXX@example.com"
    ,
    "PassengerDetails": 
      "Passengers": 
        "Passenger": [
          
            "PassengerNum": "1",
            "Title": "MR",
            "LastName": "XXXX",
            "FirstName": "XXXXX",
            "PassType": "ADT",
            "Age": "30",
            "DateOfBirth": "05OCT1983"
          ,
          
            "PassengerNum": "2",
            "Title": "MS",
            "LastName": "XXX",
            "FirstName": "XXX",
            "PassType": "ADT",
            "Age": "19",
            "DateOfBirth": "03JUN1994"
          
        ]
      
    ,
    "Onward": 
      "Flights": 
        "Flight": [
          
            "SegmentNum": "1",
            "Vendor": "AI",
            "FltNum": "935",
            "Class": "Y",
            "StartDt": "20141010",
            "StartAirport": "CCJ",
            "EndAirport": "BOM",
            "Status": "NN",
            "StartTm": "1300",
            "EndTm": "1530",
            "DtChg": "00"
          ,
          
            "SegmentNum": "2",
            "Vendor": "AI",
            "FltNum": "935",
            "Class": "Y",
            "StartDt": "20141010",
            "StartAirport": "BOM",
            "EndAirport": "DXB",
            "Status": "NN",
            "StartTm": "1700",
            "EndTm": "2000",
            "DtChg": "00"
          
        ]
      
    ,
    "ReturnTrip": 
      "Flights": 
        "Flight": [
          
            "SegmentNum": "1",
            "Vendor": "AI",
            "FltNum": "935",
            "Class": "Y",
            "StartDt": "20141010",
            "StartAirport": "DXB",
            "EndAirport": "BOM",
            "Status": "NN",
            "StartTm": "1300",
            "EndTm": "1530",
            "DtChg": "00"
          ,
          
            "SegmentNum": "2",
            "Vendor": "AI",
            "FltNum": "935",
            "Class": "Y",
            "StartDt": "20141010",
            "StartAirport": "BOM",
            "EndAirport": "CCJ",
            "Status": "NN",
            "StartTm": "1700",
            "EndTm": "2000",
            "DtChg": "00"
          
        ]
      
    
  

实体类 我创建了一个应该映射到的实体类。如下:

 public class EntityTicketingDetailsINReq

    public class TicketDetails
    
        [XmlElement("General")]
        public General General  get; set; 
        [XmlElement("PassengerDetails")]
        public PassengerDetails PassengerDetails  get; set; 
        [XmlElement("Onward")]
        public Onward Onward  get; set; 
        [XmlElement("ReturnTrip")]
        public ReturnTrip ReturnTrip  get; set; 
    
    public class General
    
        [XmlElement("TicketingCity")]
        public string TicketingCity  get; set; 
        [XmlElement("ContactNumber")]
        public string ContactNumber  get; set; 
        [XmlElement("Email")]
        public string Email  get; set; 
    
    public class PassengerDetails
    
        [XmlElement("Passengers")]
        public Passengers Passengers  get; set; 

    
    public class Passengers
    
        [XmlElement("Passenger")]
        public List<Passenger> Passenger  get; set; 
    
    public class Passenger
    
        [XmlElement("PassengerNum")]
        public string PassengerNum  get; set; 
        [XmlElement("Title")]
        public string Title  get; set; 
        [XmlElement("LastName")]
        public string LastName  get; set; 
        [XmlElement("FirstName")]
        public string FirstName  get; set; 
        [XmlElement("PassType")]
        public string PassType  get; set; 
        [XmlElement("Age")]
        public string Age  get; set; 
        [XmlElement("DateOfBirth")]
        public string DateOfBirth  get; set; 

    
    public class Onward
    
        [XmlElement("Flights")]
        public Flights Flights  get; set; 
    
    public class Flights
    
        [XmlElement("Flight")]
        public List<Flight> Flight  get; set; 
    
    public class Flight
    
        [XmlElement("SegmentNum")]
        public string SegmentNum  get; set; 
        [XmlElement("Vendor")]
        public string Vendor  get; set; 
        [XmlElement("FltNum")]
        public string FltNum  get; set; 
        [XmlElement("Class")]
        public string Class  get; set; 
        [XmlElement("StartDt")]
        public string StartDt  get; set; 
        [XmlElement("StartAirport")]
        public string StartAirport  get; set; 
        [XmlElement("EndAirport")]
        public string EndAirport  get; set; 
        [XmlElement("Status")]
        public string Status  get; set; 
        [XmlElement("StartTm")]
        public string StartTm  get; set; 
        [XmlElement("EndTm")]
        public string EndTm  get; set; 
        [XmlElement("DtChg")]
        public string DtChg  get; set; 

    

    public class ReturnTrip
    
        [XmlElement("Flights")]
        public Flights Flights  get; set; 
    

我的尝试 现在这就是我正在做的反序列化。:

var Jsonticketdetails = new EntityTicketingDetailsINReq.TicketDetails();
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(EntityTicketingDetailsINReq.TicketDetails));
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(Jsoncontent));
Jsonticketdetails = (EntityTicketingDetailsINReq.TicketDetails)ser.ReadObject(ms);

但是,映射不成功。 JSON 中的值未设置为实体对象。一切都是空的。我一直在研究这个问题一段时间,我真的很困惑。有人能告诉我我做错了什么以及需要做什么来解决这个问题吗?

PS:我需要 [XMLElement] 因为我使用相同的实体类来存储从 XML 请求反序列化的值。

【问题讨论】:

这本身并不能回答您的问题,但您可能想查看 JSON.net。我一直使用DataContractJsonSerializer,因为我认为切换起来太麻烦了,但我确实发现它实际上花费了我十分钟是值得的。当然,我没有任何关联,但它只是更好,更易于使用和调试,而且据称速度也更快。 当然,我会马上阅读。必须找到解决方案。谢谢 【参考方案1】:

尝试在EntityTicketingDetailsINReq 类中添加一个名为 Root 的新类,如下所示。

public class EntityTicketingDetailsINReq

    public class Root
    
        public TicketDetails TicketDetails  get; set; 
    

    // other classes omitted

然后将其反序列化为Root

DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(EntityTicketingDetailsINReq.Root));
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(Jsoncontent));
var root = (EntityTicketingDetailsINReq.Root)ser.ReadObject(ms);

它应该可以工作

PS:XmlElement 是不必要的,你可以把它们都去掉

【讨论】:

您不认为“EntityTicketingDetailsINReq”目前正在充当根吗?这还不够吗? @antony.ouseph.k,我觉得还不够,TicketDetails 需要另一个容器。 我需要 XML 元素,因为相同的实体类被用于将 XML 请求映射到其中。我正在为 XML 和 JSON 反序列化使用 1 个实体类 @antony.ouseph.k,如果xml元素和属性名相同,xml元素可以省略,可以直接使用XmlSerializer反序列化,但是强制转换为TicketDetails而是【参考方案2】:

您正在使用 DataContractJsonSerializer 但没有使用 DataContract 而是使用 XMLelement 属性。

[DataContract]
public class MyClass

    [DataMember]
    public string myId  get; set; 

    [DataMember]
    public List<MyClass2> otherClasses  get; set; 


[DataContract]
public class MyClass2

    [DataMember]
    public string myId  get; set; 

    [DataMember]
    public int someNumber  get; set; 

尝试使用以下属性,看看是否适合您

【讨论】:

哦..实际上可能就是这样。让我检查一下。问题是我也使用相同的实体类来反序列化 XML 请求(2 合 1)。有没有办法让一个实体类同时适用于 XML 和 JSON? 您可以使用新的 DataContractSerializer(typeof(MyClass));然后使用 XmlDictionaryWriter。这里的例子***.com/questions/11142280/…

以上是关于无法反序列化 JSON 内容的主要内容,如果未能解决你的问题,请参考以下文章

反序列化 Json 出现错误“无法反序列化当前 JSON 数组”

从 JSON 反序列化重复字典

Json 反序列化 C#

无法反序列化 JSON 响应

Json.JsonSerializationException : 无法反序列化当前 JSON 对象

C# Json反序列化 数据协定类型 无法反序列化 由于未找到必需的数据成员