我正在尝试从 WCF 服务中的请求标头恢复列表键值。我可以恢复单个属性,但找不到如何恢复列表。
这是我的电话:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
<soapenv:Header>
<tem:header1>Header 1</tem:header1>
<tem:Properties>
<tem:property>
<key>KEY.ONE</key>
<value>value1</value>
</tem:property>
<tem:property>
<key>KEY.TWO</key>
<value>value2</value>
</tem:property>
</tem:Properties>
</soapenv:Header>
<soapenv:Body>
<tem:function1>
<tem:param1>100</tem:param1>
</tem:function1>
</soapenv:Body>
</soapenv:Envelope>
这就是我恢复"header1"的方式:
MessageHeaders headers = OperationContext.Current.IncomingMessageHeaders;
string header1 = headers.GetHeader<string>("header1", "http://tempuri.org/");
我以为我可以使用这样的东西:
IDictionary<string, string> properties = headers.GetHeader<Dictionary<string, string>>("Properties", "http://tempuri.org/");
但属性始终为空。
正如MSDN所说,GetHeader<T>(string, string)
方法只能返回由DataContractSerializer
序列化的标头,这意味着您的property
对象应作为.NET类型存在。
相反,您可以做的是使用GetHeader<T>(string, string, XmlObjectSerializer)
它使用序列化程序来反序列化标头值的内容并返回它。
为此,您需要实现自己的序列化程序,该序列化程序将读取内容并返回字典。我认为这样的事情会起作用(取决于key
和value
是严格按照这个顺序还是可以交换(。另外,我没有检查命名空间会发生什么。
public class MySerializer : XmlObjectSerializer
{
public override object ReadObject(XmlDictionaryReader reader, bool verifyObjectName)
{
reader.ReadFullStartElement();
Dictionary<string, string> r = new Dictionary<string, string>();
while (reader.IsStartElement("property"))
{
reader.ReadFullStartElement("property");
reader.ReadFullStartElement("key");
string key = reader.ReadContentAsString();
reader.ReadEndElement();
reader.ReadFullStartElement("value");
string value = reader.ReadContentAsString();
reader.ReadEndElement();
r.Add(key, value);
reader.ReadEndElement();
reader.MoveToContent();
}
return r;
}
public override void WriteStartObject(XmlDictionaryWriter writer, object graph)
{
throw new NotImplementedException();
}
public override void WriteObjectContent(XmlDictionaryWriter writer, object graph)
{
throw new NotImplementedException();
}
public override void WriteEndObject(XmlDictionaryWriter writer)
{
throw new NotImplementedException();
}
public override bool IsStartObject(XmlDictionaryReader reader)
{
throw new NotImplementedException();
}
}