2012-07-26 116 views
7

我有以下XML響應我想使用XmlSerializer進行反序列化。當我刪除對XML序列化程序的調用時,我沒有發現任何錯誤。每次我使用XmlSerializer時,我都會遇到 異常。我錯過了什麼?使用XmlSerializer反序列化XML響應時缺失根元素

的例外是:

System.Xml.XmlException: Root element is missing. 
    at System.Xml.XmlTextReaderImpl.Throw(Exception e) 
    at System.Xml.XmlTextReaderImpl.ParseDocumentContent() 
    at System.Xml.XmlTextReaderImpl.Read() 
    at System.Xml.XmlTextReader.Read() 
    at System.Xml.XmlReader.MoveToContent() 
    at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderSubmitReportResponse.Read5_NeweggAPIResponse() 

XML文檔是:

<?xml version="1.0" encoding="utf-8"?> 
<NeweggAPIResponse> 
    <IsSuccess>true</IsSuccess> 
    <OperationType>OrderListReportResponse</OperationType> 
    <SellerID>myID</SellerID> 
    <ResponseBody> 
     <ResponseList> 
      <ResponseInfo> 
       <RequestId>XXXXXXXX</RequestId> 
       <RequestType>ORDER_LIST_REPORT</RequestType> 
       <RequestDate>07/26/2012 09:27:06</RequestDate> 
       <RequestStatus>SUBMITTED</RequestStatus> 
      </ResponseInfo> 
     </ResponseList> 
    </ResponseBody> 
</NeweggAPIResponse> 

我對XmlSerializer的電話是:

XmlSerializer serializer = new XmlSerializer(typeof(SubmitReportResponse)); 
reportReq = serializer.Deserialize(respStream) as SubmitReportResponse; 

SubmitReportResponse類是:

public enum RequestStatus 
{ 
    ALL, 
    SUBMITTED, 
    IN_PROGRESS, 
    FINISHED, 
    CANCELLED 
} 

/// <summary> 
/// TODO: Update summary. 
/// </summary> 
[XmlRoot("NeweggAPIResponse")] 
public class SubmitReportResponse 
{ 
    public string IsSuccess { get; set; } 
    public string OperationType { get; set; } 
    public string SellerID { get; set; } 
    public ReportResponseBody ResponseBody { get; set; } 

    public SubmitReportResponse() 
    { 
     ResponseBody = new ReportResponseBody(); 
    } 
} 

public class ReportResponseBody 
{ 
    public string Memo { get; set; } 
    public ReportResponseList[] ResponseList { get; set; } 



    public ReportResponseBody() 
    { 

     ResponseList = new ReportResponseList[0]; 
    } 
} 

public class ReportResponseList 
{ 
    public ResponseInfo[] ResponseInfo { get; set; } 

    public ReportResponseList() 
    { 
     ResponseInfo = new ResponseInfo[0]; 
    } 

} 

public class ResponseInfo 
{ 
    public string RequestId { get; set; } 
    public string RequestType { get; set; } 
    public string RequestDate { get; set; } 
    public RequestStatus RequestStatus { get; set; } 

    public ResponseInfo() 
    { 
     RequestStatus = new RequestStatus(); 
    } 
} 

編輯:

請求代碼:

  HttpWebRequest request = WebRequest.Create(endpoint) as HttpWebRequest; 
      request.Proxy = null; 
      request.Method = "POST"; 
      //Specify the xml/Json content types that are acceptable. 
      request.ContentType = "application/xml"; 
      request.Accept = "application/xml"; 

      //Attach authorization information 
      request.Headers.Add("Authorization", apikey); 
      request.Headers.Add("Secretkey", secretkey); 

      GetOrderListRequest requestObj = new GetOrderListRequest(); 
      requestObj.OperationType = OperationType.OrderListReportRequest; 
      requestObj.RequestBody = new OrderListRequestBody(); 
      requestObj.RequestBody.OrderReportCriteria = new OrderReportCriteria(); 
      requestObj.RequestBody.OrderReportCriteria.Status = 3; 
      requestObj.RequestBody.OrderReportCriteria.KeywordsType = 0; 
      requestObj.RequestBody.OrderReportCriteria.OrderDateFrom = "2012-01-01"; 
      requestObj.RequestBody.OrderReportCriteria.OrderDateTo = "2012-07-26"; 
      requestObj.RequestBody.OrderReportCriteria.OrderDownloaded = "false"; 

      string requestBody = SerializeToString(requestObj); 

      byte[] byteStr = Encoding.UTF8.GetBytes(requestBody); 
      request.ContentLength = byteStr.Length; 

      using (Stream stream = request.GetRequestStream()) 
      { 
       stream.Write(byteStr, 0, byteStr.Length); 
      } 

      //Parse the response 
      using (HttpWebResponse response = request.GetResponse() as HttpWebResponse) 
      { 
       //Business error 
       if (response.StatusCode != HttpStatusCode.OK) 
       { 
        Console.WriteLine(string.Format("Error: response status code is{0}, at time:{1}", response.StatusCode, DateTime.Now.ToString())); 

        return; 
       } 
       else if (response.StatusCode == HttpStatusCode.OK)//Success 
       { 
        using (Stream respStream = response.GetResponseStream()) 
        { 
         StreamReader readerOK = new StreamReader(respStream); 
         //Console.WriteLine(String.Format("Result:{0}", DateTime.Now.ToString())); 
         Console.WriteLine(String.Format("{0}", readerOK.ReadToEnd())); 

         XmlSerializer serializer = new XmlSerializer(typeof(SubmitReportResponse)); 
         reportReq = serializer.Deserialize(respStream) as SubmitReportResponse; 
        } 
       } 
      } 


    public string SerializeToObj(object obj) 
    { 

     XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); 
     ns.Add("", ""); 
     XmlWriterSettings settings = new XmlWriterSettings(); 
     settings.OmitXmlDeclaration = true; 
     settings.Encoding = new UTF8Encoding(false); 
     settings.Indent = true; 
     XmlSerializer xs = new XmlSerializer(obj.GetType()); 
     MemoryStream ms = new MemoryStream(); 

     // xs.Serialize(ms, obj,ns); 


     XmlWriter writer = XmlWriter.Create(ms, settings); 
     xs.Serialize(writer, obj, ns); 

     return Encoding.UTF8.GetString(ms.ToArray()); 
    } 

分辨率:

看來,呼籲Console.WriteLine(String.Format("{0}", readerOK.ReadToEnd()));導致被消耗,並進行序列化不可用的流。刪除這一行允許我正確地將XML序列化到我的類中。

+0

嘗試將XmlRoot(「NeweggAPIResponse」)更改爲XmlType(「NeweggAPIResponse」)。 – Stephan 2012-07-26 17:09:57

+0

我可以在哪裏找到您檢索實際XML的代碼嗎?我已經在本地測試了您的代碼,並且它在我從磁盤加載XML文件時起作用,但需要注意的是您不需要中間ReportResponseList類。 – dash 2012-07-26 17:19:09

+0

@dash添加了調用代碼。請參閱編輯。斯蒂芬:那沒用。 – 2012-07-26 17:56:31

回答

10

調用Console.WriteLine(String.Format("{0}", readerOK.ReadToEnd()));會導致流被消耗並且不可用於序列化。

刪除此行允許我正確地將XML序列化到我的類中。

+3

您可以設置Stream.Position = 0 – Brij 2013-06-25 13:48:59