Sid*_*idC 8 c# json json.net restsharp
我查看了该问题的答案,发现无效字符会导致引发此错误的问题。我的问题有点不同,我使用RestSharp进行API调用,如下所示:
private static T Execute<T>(IRestRequest request, string baseUrl) where T : class, new()
{
var client = new RestClient(baseUrl);
var response = client.Execute<T>(request);
if (response.ErrorException != null)
{
Console.WriteLine(
"Error: Exception: {0}, Headers: {1}, Content: {2}, Status Code: {3}",
response.ErrorException,
response.Headers,
response.Content,
response.StatusCode);
}
return response.Data;
}
public static ProPayResponse MerchantSignUpForProPay()
{
var baseUrl = "https://xmltestapi.propay.com/ProPayAPI";
var request = BuildMerchantTestData();
var restRequest = CreateRestRequest("SignUp", Method.PUT);
restRequest.AddJsonBody(request);
return Execute<ProPayResponse>(restRequest, baseUrl);
}
private static async Task<RestRequest> CreateRestRequest(string resource, Method method)
{
var credentials = GetCredentials();
var restRequest = new RestRequest { Resource = resource, Method = method, RequestFormat = DataFormat.Json, };
restRequest.AddHeader("accept", "application/json");
restRequest.AddHeader("Authorization", credentials);
return restRequest;
}
private static string GetCredentials()
{
var termId = "myterm"; // put affiliate term id here, if you have it
var certString = "mycertString"; // put affiliate cert string here
var encodedCredentials = Convert.ToBase64String(Encoding.Default.GetBytes(certString + ":" + termId));
var credentials = $"Basic {encodedCredentials}";
return credentials;
}
Run Code Online (Sandbox Code Playgroud)
异常的完整堆栈跟踪如下:
Error: Exception: System.Xml.XmlException: '=' is an unexpected token. The expected token is ';'. Line 26, position 43.
at 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.HandleEntityReference(Boolean isInAttributeValue, EntityExpandType expandType, Int32& charRefEndPos)
at System.Xml.XmlTextReaderImpl.ParseText(Int32& startPos, Int32& endPos, Int32& outOrChars)
at System.Xml.XmlTextReaderImpl.FinishPartialValue()
at System.Xml.XmlTextReaderImpl.get_Value()
at System.Xml.Linq.XContainer.ContentReader.ReadContentFrom(XContainer rootContainer, XmlReader r)
at System.Xml.Linq.XContainer.ReadContentFrom(XmlReader r)
at System.Xml.Linq.XContainer.ReadContentFrom(XmlReader r, LoadOptions o)
at System.Xml.Linq.XDocument.Load(XmlReader reader, LoadOptions options)
at System.Xml.Linq.XDocument.Parse(String text, LoadOptions options)
at RestSharp.Deserializers.XmlDeserializer.Deserialize[T](IRestResponse response)
at RestSharp.RestClient.Deserialize[T](IRestRequest request, IRestResponse raw), Headers: System.Collections.Generic.List`1[RestSharp.Parameter], Content:
Run Code Online (Sandbox Code Playgroud)
运行此代码时,我确实注意到在堆栈跟踪的内容部分中引发了HTTP 404。
我认为这意味着我有一个错误,baseURl但不确定,并想知道是否是这种情况,或者我的代码是否还有其他问题?
更新:
在进一步研究了这个问题之后,我认为引发了错误,因为在发送之前我没有将模型对象序列化为JSON RestRequest。
发出请求之前,我需要序列化所有对象吗?
更新2: 由于第二眼,我更正了URL。现在,当我运行我的应用程序时,将引发以下错误:
Error: Exception: System.Xml.XmlException: Data at the root level is invalid. Line 1, position 1.
at System.Xml.XmlTextReaderImpl.Throw(Exception e)
at System.Xml.XmlTextReaderImpl.Throw(String res, String arg)
at System.Xml.XmlTextReaderImpl.ParseRootLevelWhitespace()
at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
at System.Xml.XmlTextReaderImpl.Read()
at System.Xml.Linq.XDocument.Load(XmlReader reader, LoadOptions options)
at System.Xml.Linq.XDocument.Parse(String text, LoadOptions options)
at RestSharp.Deserializers.XmlDeserializer.Deserialize[T](IRestResponse response)
at RestSharp.RestClient.Deserialize[T](IRestRequest request, IRestResponse raw), Message: Data at the root level is invalid. Line 1, position 1., Headers: System.Collections.Generic.List`1[RestSharp.Parameter], Content: ?<?xml version="1.0" encoding="utf-8"?>
Run Code Online (Sandbox Code Playgroud)
在更新 2 之后,RestSharp 似乎在 XML 的开头引入了一个意外的字符。
这是来自错误消息:
Content: ?<?xml version="1.0" encoding="utf-8"?>
Run Code Online (Sandbox Code Playgroud)
前面的问号<?xml就是问题所在。它不是 XML 的有效字符,并且会导致 XML 解析器抛出错误。
我的最佳猜测是响应中的 XML 内容开头有一个 UTF-8 字节顺序标记 (BOM)。从技术上讲,BOM 不是有效的字符,您的日志记录代码/框架正在将其转换为?用于显示的字符。
您可以通过调用.ExecuteTaskAsync(request)而不是.ExecuteTaskAsync<T>(request)查看返回的数据来测试这一点response.RawBytes。如果返回的前 3 个字节是,0xEF 0xBB 0xBF则您的响应中包含 BOM。
快速解决
这应该可以完成工作,并且需要最少的代码更改。
restRequest.OnBeforeDeserialization = resp => {
if (resp.RawBytes.Length >= 3 && resp.RawBytes[0] == 0xEF && resp.RawBytes[1] == 0xBB && resp.RawBytes[2] == 0xBF)
{
// Copy the data but with the UTF-8 BOM removed.
var newData = new byte[resp.RawBytes.Length - 3];
Buffer.BlockCopy(resp.RawBytes, 3, newData, 0, newData.Length);
resp.RawBytes = newData;
// Force re-conversion to string on next access
resp.Content = null;
}
};
Run Code Online (Sandbox Code Playgroud)
这将确保尽早删除 BOM。当它转换为字符串进行 XML 解析时,BOM 将不存在。
更长的修复
您可以为 XML 创建自己的反序列化器,它会检测 XML 开头的 BOM 并在解析之前将其删除。这里的步骤是:
RestSharp.Deserializers.XmlDeserializer. 这将需要一个方法重写:public override T Deserialize<T>(IRestResponse response)
{
if (string.IsNullOrEmpty(response.Content))
return default(T);
if (response.Content[0] == '\uFEFF')
response.Content = response.Content.Substring(1);
return base.Deserialize<T>(response);
}
Run Code Online (Sandbox Code Playgroud)
RestSharp.Deserializers.XmlRestSerializer并调用该类。.WithXmlDeserializer().AddHandler("application/xml", () => xmlRestSerializer)您的RestClient实例。
xmlRestSerializer是您在上面第 3 步中创建的对象。application/xml为其他内容,具体取决于 REST API 返回的内容。| 归档时间: |
|
| 查看次数: |
281 次 |
| 最近记录: |