WCF 消息格式化程序未格式化故障消息
WCF Message Formatter not formatting Fault Message
我有一个 WCF 服务,我正在其中更改肯定响应的前缀,但是在错误响应中只有部分消息被更改。
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SOAP-ENV:Body>
<s:Fault
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<faultcode>s:Client</faultcode>
<faultstring xml:lang="en-GB">Unable to satisfy web service request at this time.This may relate to the format or sequence of the requests, the status of the requested information or reflect a service issue.</faultstring>
</s:Fault>
</SOAP-ENV:Body>
SOAP-ENV 是正确的语法,但是正如您在记录错误时看到的那样,前缀是 s:
。
正在做这项工作的 class 在这里
public class ProposalMessage : Message
{
private readonly Message message;
public ProposalMessage(Message message)
{
this.message = message;
}
public override MessageHeaders Headers
{
get { return this.message.Headers; }
}
public override MessageProperties Properties
{
get { return this.message.Properties; }
}
public override MessageVersion Version
{
get { return this.message.Version; }
}
protected override void OnWriteStartBody(XmlDictionaryWriter writer)
{
writer.WriteStartElement("Body", "http://schemas.xmlsoap.org/soap/envelope/");
}
protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
{
this.message.WriteBodyContents(writer);
}
protected override void OnWriteStartEnvelope(XmlDictionaryWriter writer)
{
writer.WriteStartElement("SOAP-ENV", "Envelope", "http://schemas.xmlsoap.org/soap/envelope/");
writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance");
writer.WriteAttributeString("xmlns", "xsd", null, "http://www.w3.org/2001/XMLSchema");
}
}
而且我还需要去掉它的命名空间。
我已经尝试了很多东西,none 都奏效了。
下面是我尝试过的其中一种方法\事情的示例
protected override void OnWriteDetail(XmlDictionaryWriter writer)
{
writer.WriteStartElement("Fault", "http://schemas.xmlsoap.org/soap/envelope/");
}
但是这不适合覆盖
查看了这里的一些文档 https://docs.microsoft.com/en-us/dotnet/api/system.servicemodel.channels.messagefault.onwritedetail?view=netframework-4.7.2 我无法使任何东西工作。
任何有关格式化故障消息的帮助都将非常有用
您可以尝试以下解决方案:
public class CustomMessage : Message
{
private readonly Message message;
public CustomMessage(Message message)
{
this.message = message;
}
public override MessageHeaders Headers
{
get { return this.message.Headers; }
}
public override MessageProperties Properties
{
get { return this.message.Properties; }
}
public override MessageVersion Version
{
get { return this.message.Version; }
}
protected override void OnWriteStartBody(XmlDictionaryWriter writer)
{
writer.WriteStartElement("Body", "http://schemas.xmlsoap.org/soap/envelope/");
}
protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
{
this.message.WriteBodyContents(writer);
}
protected override void OnWriteStartEnvelope(XmlDictionaryWriter writer)
{
writer.WriteStartElement("SOAP-ENV", "Envelope", "http://schemas.xmlsoap.org/soap/envelope/");
writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance");
writer.WriteAttributeString("xmlns", "xsd", null, "http://www.w3.org/2001/XMLSchema");
}
}
这是自定义消息。
public class MyCustomMessageFormatter : IDispatchMessageFormatter
{
private readonly IDispatchMessageFormatter formatter;
public MyCustomMessageFormatter(IDispatchMessageFormatter formatter)
{
this.formatter = formatter;
}
public void DeserializeRequest(Message message, object[] parameters)
{
this.formatter.DeserializeRequest(message, parameters);
}
public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result)
{
var message = this.formatter.SerializeReply(messageVersion, parameters, result);
return new CustomMessage(message);
}
}
这是 MyCustomMessageFormatter。
[AttributeUsage(AttributeTargets.Method)]
public class MyMessageAttribute : Attribute, IOperationBehavior
{
public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters) { }
public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation) { }
public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
{
var serializerBehavior = operationDescription.Behaviors.Find<DataContractSerializerOperationBehavior>();
if (dispatchOperation.Formatter == null)
{
((IOperationBehavior)serializerBehavior).ApplyDispatchBehavior(operationDescription, dispatchOperation);
}
IDispatchMessageFormatter innerDispatchFormatter = dispatchOperation.Formatter;
dispatchOperation.Formatter = new MyCustomMessageFormatter(innerDispatchFormatter);
}
public void Validate(OperationDescription operationDescription) { }
}
这是 MyMessageAttribute.We 将 MyCustomMessageFormatter 添加到行为中。
[MyMessage]
public Result GetUserData(string name)
{....
我们将刚刚定义的行为添加到方法中。
我有一个 WCF 服务,我正在其中更改肯定响应的前缀,但是在错误响应中只有部分消息被更改。
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SOAP-ENV:Body>
<s:Fault
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<faultcode>s:Client</faultcode>
<faultstring xml:lang="en-GB">Unable to satisfy web service request at this time.This may relate to the format or sequence of the requests, the status of the requested information or reflect a service issue.</faultstring>
</s:Fault>
</SOAP-ENV:Body>
SOAP-ENV 是正确的语法,但是正如您在记录错误时看到的那样,前缀是 s:
。
正在做这项工作的 class 在这里
public class ProposalMessage : Message
{
private readonly Message message;
public ProposalMessage(Message message)
{
this.message = message;
}
public override MessageHeaders Headers
{
get { return this.message.Headers; }
}
public override MessageProperties Properties
{
get { return this.message.Properties; }
}
public override MessageVersion Version
{
get { return this.message.Version; }
}
protected override void OnWriteStartBody(XmlDictionaryWriter writer)
{
writer.WriteStartElement("Body", "http://schemas.xmlsoap.org/soap/envelope/");
}
protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
{
this.message.WriteBodyContents(writer);
}
protected override void OnWriteStartEnvelope(XmlDictionaryWriter writer)
{
writer.WriteStartElement("SOAP-ENV", "Envelope", "http://schemas.xmlsoap.org/soap/envelope/");
writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance");
writer.WriteAttributeString("xmlns", "xsd", null, "http://www.w3.org/2001/XMLSchema");
}
}
而且我还需要去掉它的命名空间。
我已经尝试了很多东西,none 都奏效了。
下面是我尝试过的其中一种方法\事情的示例
protected override void OnWriteDetail(XmlDictionaryWriter writer)
{
writer.WriteStartElement("Fault", "http://schemas.xmlsoap.org/soap/envelope/");
}
但是这不适合覆盖
查看了这里的一些文档 https://docs.microsoft.com/en-us/dotnet/api/system.servicemodel.channels.messagefault.onwritedetail?view=netframework-4.7.2 我无法使任何东西工作。
任何有关格式化故障消息的帮助都将非常有用
您可以尝试以下解决方案:
public class CustomMessage : Message
{
private readonly Message message;
public CustomMessage(Message message)
{
this.message = message;
}
public override MessageHeaders Headers
{
get { return this.message.Headers; }
}
public override MessageProperties Properties
{
get { return this.message.Properties; }
}
public override MessageVersion Version
{
get { return this.message.Version; }
}
protected override void OnWriteStartBody(XmlDictionaryWriter writer)
{
writer.WriteStartElement("Body", "http://schemas.xmlsoap.org/soap/envelope/");
}
protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
{
this.message.WriteBodyContents(writer);
}
protected override void OnWriteStartEnvelope(XmlDictionaryWriter writer)
{
writer.WriteStartElement("SOAP-ENV", "Envelope", "http://schemas.xmlsoap.org/soap/envelope/");
writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance");
writer.WriteAttributeString("xmlns", "xsd", null, "http://www.w3.org/2001/XMLSchema");
}
}
这是自定义消息。
public class MyCustomMessageFormatter : IDispatchMessageFormatter
{
private readonly IDispatchMessageFormatter formatter;
public MyCustomMessageFormatter(IDispatchMessageFormatter formatter)
{
this.formatter = formatter;
}
public void DeserializeRequest(Message message, object[] parameters)
{
this.formatter.DeserializeRequest(message, parameters);
}
public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result)
{
var message = this.formatter.SerializeReply(messageVersion, parameters, result);
return new CustomMessage(message);
}
}
这是 MyCustomMessageFormatter。
[AttributeUsage(AttributeTargets.Method)]
public class MyMessageAttribute : Attribute, IOperationBehavior
{
public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters) { }
public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation) { }
public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
{
var serializerBehavior = operationDescription.Behaviors.Find<DataContractSerializerOperationBehavior>();
if (dispatchOperation.Formatter == null)
{
((IOperationBehavior)serializerBehavior).ApplyDispatchBehavior(operationDescription, dispatchOperation);
}
IDispatchMessageFormatter innerDispatchFormatter = dispatchOperation.Formatter;
dispatchOperation.Formatter = new MyCustomMessageFormatter(innerDispatchFormatter);
}
public void Validate(OperationDescription operationDescription) { }
}
这是 MyMessageAttribute.We 将 MyCustomMessageFormatter 添加到行为中。
[MyMessage]
public Result GetUserData(string name)
{....
我们将刚刚定义的行为添加到方法中。