ReadAsAsync Class 使用 XmlMediaTypeFormatter 或其他反序列化
ReadAsAsync Class using XmlMediaTypeFormatter or other Deserialization
我正在尝试反序列化以下 XML:
<?xml version="1.0" encoding="UTF-8"?>
<jobInfo
xmlns="http://www.force.com/2009/06/asyncapi/dataload">
<id>asjdkfljasl;kdf</id>
<operation>query</operation>
<object>jsdkfjsakldjakl</object>
...
</jobInfo>
我有以下代码可以发出 POST 请求并成功运行,但无法反序列化到我的 class.
client.DefaultRequestHeaders.Add("X-SFDC-Session", binding.SessionHeaderValue.sessionId);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", binding.SessionHeaderValue.sessionId);
var content = new StringContent(createJobXml, Encoding.UTF8, "application/xml");
content.Headers.ContentType = new MediaTypeHeaderValue("application/xml");
HttpResponseMessage response = await client.PostAsync(
$"https://{SERVER_INSTANCE}.salesforce.com/services/async/43.0/job", content
);
response.EnsureSuccessStatusCode();
jobInfo job = await response.Content.ReadAsAsync<jobInfo >(new List<MediaTypeFormatter>() {
new XmlMediaTypeFormatter { UseXmlSerializer = true },
new JsonMediaTypeFormatter()
});
但是我收到错误
No MediaTypeFormatter is available to read an object of type 'jobInfo ' from content with media type 'application/xml',
我的 jobInfo 是使用 xsd.exe doc.xml
、xsd.exe doc.xsd /classes
生成的
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.81.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.force.com/2009/06/asyncapi/dataload")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://www.force.com/2009/06/asyncapi/dataload", IsNullable = false)]
public partial class jobInfo
{
private string idField;
private string operationField;
private string objectField;
...
public string id
{
get {
return this.idField;
}
set {
this.idField = value;
}
}
public string operation
{
get {
return this.operationField;
}
set {
this.operationField = value;
}
}
...
}
为了正确反序列化我错过了什么?
这表明我应该将其作为字符串读取:
但这表明它应该 "just work"
我也尝试过(在使用 xsd 将 xml 转换为 class 之前使用 class Bulkv1Job)
[DataContract]
public class Bulkv1Job
{
[DataMember]
string id { get; set; }
[DataMember]
string operation { get; set; }
[DataMember]
string @object { get; set; }
...
}
和
[XmlRoot("jobInfo")]
public class Bulkv1Job
{
[XmlElement("id")]
string id { get; set; }
[XmlElement("operation")]
string operation { get; set; }
...
}
嗯,我不是 soap 专家,但如果我没记错的话,它应该在你的属性上有像 [DataMember] 这样的装饰器,在你的 class 上应该有 [DataContract(NameSpace="jobInfo")] .
您可以看到,在第一个建议中,您提供的人使用 [XmlRoot] 和 [XmlElement]
你也可以看看WCF Datacontract, some fields do not deserialize,也许对你有帮助
使用
测试后
var s = await response.content.readasstringasync();
var buffer = encoding.utf8.getbytes(s);
using (var stream = new memorystream(buffer)) {
var serializer = new xmlserializer(typeof(jobinfo)); // FAILED LINE
var jobinfo = (jobinfo)serializer.deserialize(stream);
//then do whatever you want
return jobinfo;
}
我发现由于 class 保护错误,序列化程序在上述行中失败。
确保 jobInfo
class 是 public 并且可以访问,错误消失并且 deserialize(stream)
工作。
删除该代码并使用 readAsAsync<jobInfo>(...)
之后可以正常工作。
感谢@Ryan
我正在尝试反序列化以下 XML:
<?xml version="1.0" encoding="UTF-8"?>
<jobInfo
xmlns="http://www.force.com/2009/06/asyncapi/dataload">
<id>asjdkfljasl;kdf</id>
<operation>query</operation>
<object>jsdkfjsakldjakl</object>
...
</jobInfo>
我有以下代码可以发出 POST 请求并成功运行,但无法反序列化到我的 class.
client.DefaultRequestHeaders.Add("X-SFDC-Session", binding.SessionHeaderValue.sessionId);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", binding.SessionHeaderValue.sessionId);
var content = new StringContent(createJobXml, Encoding.UTF8, "application/xml");
content.Headers.ContentType = new MediaTypeHeaderValue("application/xml");
HttpResponseMessage response = await client.PostAsync(
$"https://{SERVER_INSTANCE}.salesforce.com/services/async/43.0/job", content
);
response.EnsureSuccessStatusCode();
jobInfo job = await response.Content.ReadAsAsync<jobInfo >(new List<MediaTypeFormatter>() {
new XmlMediaTypeFormatter { UseXmlSerializer = true },
new JsonMediaTypeFormatter()
});
但是我收到错误
No MediaTypeFormatter is available to read an object of type 'jobInfo ' from content with media type 'application/xml',
我的 jobInfo 是使用 xsd.exe doc.xml
、xsd.exe doc.xsd /classes
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.81.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.force.com/2009/06/asyncapi/dataload")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://www.force.com/2009/06/asyncapi/dataload", IsNullable = false)]
public partial class jobInfo
{
private string idField;
private string operationField;
private string objectField;
...
public string id
{
get {
return this.idField;
}
set {
this.idField = value;
}
}
public string operation
{
get {
return this.operationField;
}
set {
this.operationField = value;
}
}
...
}
为了正确反序列化我错过了什么?
这表明我应该将其作为字符串读取:
但这表明它应该 "just work"
我也尝试过(在使用 xsd 将 xml 转换为 class 之前使用 class Bulkv1Job)
[DataContract]
public class Bulkv1Job
{
[DataMember]
string id { get; set; }
[DataMember]
string operation { get; set; }
[DataMember]
string @object { get; set; }
...
}
和
[XmlRoot("jobInfo")]
public class Bulkv1Job
{
[XmlElement("id")]
string id { get; set; }
[XmlElement("operation")]
string operation { get; set; }
...
}
嗯,我不是 soap 专家,但如果我没记错的话,它应该在你的属性上有像 [DataMember] 这样的装饰器,在你的 class 上应该有 [DataContract(NameSpace="jobInfo")] . 您可以看到,在第一个建议中,您提供的人使用 [XmlRoot] 和 [XmlElement]
你也可以看看WCF Datacontract, some fields do not deserialize,也许对你有帮助
使用
测试后var s = await response.content.readasstringasync();
var buffer = encoding.utf8.getbytes(s);
using (var stream = new memorystream(buffer)) {
var serializer = new xmlserializer(typeof(jobinfo)); // FAILED LINE
var jobinfo = (jobinfo)serializer.deserialize(stream);
//then do whatever you want
return jobinfo;
}
我发现由于 class 保护错误,序列化程序在上述行中失败。
确保 jobInfo
class 是 public 并且可以访问,错误消失并且 deserialize(stream)
工作。
删除该代码并使用 readAsAsync<jobInfo>(...)
之后可以正常工作。
感谢@Ryan