11

I have the following XML response I am trying to deserialize using XmlSerializer. When I remove the call to XML serializer I throw no errors. Every time I use XmlSerializer I get an exception. What am I missing?

Exception is:

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 Doc is:

<?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>

My call to XmlSerializer is:

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

SubmitReportResponse class is:

    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();
    }
}

EDIT:

Requesting Code:

            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());
    }

Resolution:

It seems that calling Console.WriteLine(String.Format("{0}", readerOK.ReadToEnd())); causes the stream to be consumed and be unavailable for serialization. Removing this line allowed me to properly serialize the XML into my classes.

7
  • Try changing the XmlRoot("NeweggAPIResponse") to XmlType("NeweggAPIResponse"). Commented Jul 26, 2012 at 17:09
  • Can I see the code where you retrieve the actual XML please? I've tested your code locally and it works if I load the XML file from the disk, but with the caveat that you don't need the intermediate ReportResponseList class. Commented Jul 26, 2012 at 17:19
  • @dash Added calling code. Please see edit. Stephan: That didn't work. Commented Jul 26, 2012 at 17:56
  • Are you certain that the XML is as you expect? Chances are that the root element is actually missing (i.e., the XML is empty). Commented Jul 26, 2012 at 18:38
  • @JohnSaunders Now you have made me doubt myself lol. Let me check Commented Jul 26, 2012 at 18:45

1 Answer 1

20

Calling Console.WriteLine(String.Format("{0}", readerOK.ReadToEnd())); causes the stream to be consumed and be unavailable for serialization.

Removing this line allowed me to properly serialize the XML into my classes.

Sign up to request clarification or add additional context in comments.

1 Comment

You could set Stream.Position = 0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.