我正在托管SOAP ServiceHost,客户端正在发送特定消息。
该服务正在响应500内部服务器错误,因为它无法解码SOAP消息。错误原因是:
原因:“为操作GetStreamUri反序列化请求消息正文”
InnerException :“名称空间前缀'onv'未定义”
为了检查发生了什么,我们将到达的消息与servicehost解析的消息进行了比较。
我们使用Wireshark捕获了消息:
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope"
xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:onv="http://www.onvif.org/ver10/schema"
xmlns:media="http://www.onvif.org/ver10/media/wsdl">
<SOAP-ENV:Header>
<!-- security stuff -->
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<media:GetStreamUri>
<media:StreamSetup xsi:type="onv:StreamSetup">
<onv:Stream>RTP-Unicast</onv:Stream>
<onv:Transport xsi:type="onv:Transport">
<onv:Protocol>UDP</onv:Protocol>
</onv:Transport>
</media:StreamSetup>
<media:ProfileToken>cs_videoProfileTK_000</media:ProfileToken>
</media:GetStreamUri>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
我们捕获了Servicehost通过Message Inspector收到的内容:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Header>
<!-- security stuff -->
</s:Header>
<s:Body>
<media:GetStreamUri xmlns:media="http://www.onvif.org/ver10/media/wsdl">
<media:StreamSetup xsi:type="onv:StreamSetup" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<onv:Stream xmlns:onv="http://www.onvif.org/ver10/schema">RTP-Unicast</onv:Stream>
<onv:Transport xsi:type="onv:Transport" xmlns:onv="http://www.onvif.org/ver10/schema">
<onv:Protocol>UDP</onv:Protocol>
</onv:Transport>
</media:StreamSetup>
<media:ProfileToken>cs_videoProfileTK_000</media:ProfileToken>
</media:GetStreamUri>
</s:Body>
</s:Envelope>
如您所见,名称空间解析器检测到'onv'前缀,并将其分配给
<onv:Stream xmlns:onv="http://www.onvif.org/ver10/schema">RTP-Unicast</onv:Stream>
但问题是'onv'命名空间是在xsi:type属性中使用后定义的
<media:StreamSetup xsi:type="onv:StreamSetup" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
似乎XMLSerializer在属性中使用名称空间方面表现不佳。是否有使用消息格式化程序或检查程序的解决方案或解决方法?
修改 从WSDL生成的代码。
// StreamSetup class
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.34234")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://www.onvif.org/ver10/schema")]
public partial class StreamSetup : object, System.ComponentModel.INotifyPropertyChanged {
private StreamType streamField;
//ommited
[System.Xml.Serialization.XmlElementAttribute(Order=0)]
public StreamType Stream {
get {
return this.streamField;
}
set {
this.streamField = value;
this.RaisePropertyChanged("Stream");
}
}
// ommited
}
// StreamType class
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.34234")]
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://www.onvif.org/ver10/schema")]
public enum StreamType {
[System.Xml.Serialization.XmlEnumAttribute("RTP-Unicast")]
RTPUnicast,
// ommited
}
// Get Stream URI Method/Operation
[System.ServiceModel.OperationContractAttribute(Action="http://www.onvif.org/ver10/media/wsdl/GetStreamUri", ReplyAction="*")]
[System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(ConfigurationEntity))]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(DeviceEntity))]
[return: System.ServiceModel.MessageParameterAttribute(Name="MediaUri")]
ONVIF.MediaUri GetStreamUri(ONVIF.StreamSetup StreamSetup, string ProfileToken);