流异常& System.Xml.XmlException:' - '是一个意外的令牌。预期的令牌是''

时间:2012-05-15 22:01:02

标签: c# xml streamwriter

我收到StreamWriter抛出的错误,我得到的消息是:

Length = '(sw.BaseStream).Length' threw an exception of type 'System.NotSupportedException'
Position = '(sw.BaseStream).Position' threw an exception of type 'System.NotSupportedException'

堆栈跟踪:

Message: System.Xml.XmlException: '6163592' is an unexpected token. The expected token is '\'" or "".
Stack Trace: System.Xml.XmlTextReaderImpl.Throw(Exception e)
   at System.Xml.XmlTextReaderImpl.Throw(String res, String[] args)
   at System.Xml.XmlTextReaderImpl.ThrowUnexpectedToken(String expectedToken1, String expectedToken2)
   at System.Xml.XmlTextReaderImpl.ParseAttributes()
   at System.Xml.XmlTextReaderImpl.ParseElement()
   at System.Xml.XmlTextReaderImpl.ParseElementContent()
   at System.Xml.XmlTextReaderImpl.Read()
   at System.Xml.XmlLoader.LoadNode(Boolean skipOverWhitespace)
   at System.Xml.XmlLoader.LoadDocSequence(XmlDocument parentDoc)
   at System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean preserveWhitespace)
   at System.Xml.XmlDocument.Load(XmlReader reader)
   at System.Xml.XmlDocument.Load(Stream inStream)
   at BasecampManager.SendRequest(String command, String request) in C:\Inetpub\wwwroot\basecamp\Basecamp_Net_20_API_src\BasecampAPI\BasecampManager.cs:line 146

我的代码:

public XmlDocument SendRequest(string command, string request) 
{
    XmlDocument result = null;
    if (IsInitialized()) 
    {
        result = new XmlDocument();
        HttpWebRequest webRequest = null;
        HttpWebResponse webResponse = null;

        try 
        {
            string prefix = (m_SecureMode) ? "https://" : "http://";
            string url = string.Concat(prefix, m_Url, command);
            webRequest = (HttpWebRequest)WebRequest.Create(url);

            webRequest.Method = "POST";
            webRequest.ContentType = "text/xml";
            webRequest.ServicePoint.Expect100Continue = false;

            string UsernameAndPassword = string.Concat(m_Username, ":", m_Password);
            string EncryptedDetails = Convert.ToBase64String(Encoding.ASCII.GetBytes(UsernameAndPassword));
            webRequest.Headers.Add("Authorization", "Basic " + EncryptedDetails);

            //MessageBox.Show(webRequest.GetRequestStream().ToString());

            using (StreamWriter sw = new StreamWriter(webRequest.GetRequestStream()))
            {
               sw.WriteLine(request);
            }

            // Assign the response object of 'WebRequest' to a 'WebResponse' variable.

            webResponse = (HttpWebResponse)webRequest.GetResponse();

            using (StreamReader sr = new StreamReader(webResponse.GetResponseStream()))
            {
                result.Load(sr.BaseStream);
                sr.Close();
            }
        }
        catch (Exception ex) 
        {
            string ErrorXml = string.Format("<error>{0}</error>", ex.ToString());
            result.LoadXml(ErrorXml);
        }
        finally 
        {
            if (webRequest != null)
                webRequest.GetRequestStream().Close();

            if (webResponse != null)
                webResponse.GetResponseStream().Close();
        }
    }
    return result;
}

我不确定是什么问题。我检查过很多帖子,但没有什么可以帮助我。

这段代码几个月前工作得非常好。现在它自动停止工作并通过异常。通过思考它可能是VS 2005的一些问题,我尝试在VS 2005,2008,2010上运行此代码,但它不再起作用。

2 个答案:

答案 0 :(得分:6)

很可能服务器响应不再是有效的XML。

使用一些HTTP调试工具(即Fiddler)来查看响应的实际效果。或者将响应保存为文本,而不是尝试加载为XML。

答案 1 :(得分:0)

您的代码的一些建议改进:

public XmlDocument SendRequest(string command, string request)
{
    if (!IsInitialized())
        return null;

    var result = new XmlDocument();

    try
    {
        var prefix = (m_SecureMode) ? "https://" : "http://";
        var url = string.Concat(prefix, m_Url, command);
        var webRequest = (HttpWebRequest) WebRequest.Create(url);

        webRequest.Method = "POST";
        webRequest.ContentType = "text/xml";
        webRequest.ServicePoint.Expect100Continue = false;

        var UsernameAndPassword = string.Concat(m_Username, ":", m_Password);
        var EncryptedDetails = Convert.ToBase64String(Encoding.ASCII.GetBytes(UsernameAndPassword));
        webRequest.Headers.Add("Authorization", "Basic " + EncryptedDetails);

        using (var requestStream = webRequest.GetRequestStream())
        {
            using (var sw = new StreamWriter(requestStream))
            {
                sw.WriteLine(request);
            }
        }

        using (var webResponse = webRequest.GetResponse())
        {
            using (var responseStream = webResponse.GetResponseStream())
            {
                result.Load(responseStream);
            }
        }
    }
    catch (Exception ex)
    {
        result.LoadXml("<error></error>");
        result.DocumentElement.InnerText = ex.ToString();
    }
    return result;
}

您创建的实现IDisposable的所有对象都应位于using块中。您已省略WebResponse和结果Stream

此外,XmlDocument.Load可以直接接受Stream,因此无需在中间StreamReader中使用。 我还建议完全删除try / catch块,而不是强制你的调用者必须读取XML来确定是否发生了错误。但是,如果您坚持这样做,那么您至少应该使用XML API来构建XML。你不知道ex.ToString()里面有什么,所以把它扔到<error>{0}</error>的中间很可能会产生无效的XML。