WCF Message Formatter not formatting Fault Message

佐手、 提交于 2020-06-29 03:40:17

问题


I have a WCF Service where I am changing the prefix of a positive response, however on a fault response only part of the message is being changed.

<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 is the correct syntax however as you can see when logging the fault the prefix is s:.

The class that is doing the work is here

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");
    }
}

and I also need to strip out the namespace of this too.

I have tried in the a variety of things, none of which have worked.

below is an example of one of the methods \ things I have tried

protected override void OnWriteDetail(XmlDictionaryWriter writer)
{
    writer.WriteStartElement("Fault", "http://schemas.xmlsoap.org/soap/envelope/");
}

However this is not an suitable for overriding

Having looked at some of the documentation here https://docs.microsoft.com/en-us/dotnet/api/system.servicemodel.channels.messagefault.onwritedetail?view=netframework-4.7.2 I am unable to get anything to work.

Any and all help on formatting the fault message will be greate


回答1:


You can try the following solution:

  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");
        }
    }

This is CustomMessage.

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);
        }
    }

This is 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) { }
    }

This is MyMessageAttribute.We add MyCustomMessageFormatter to the behavior.

        [MyMessage]
        public Result GetUserData(string name)
        {....

We add the behavior we just defined to the method.



来源:https://stackoverflow.com/questions/62474354/wcf-message-formatter-not-formatting-fault-message

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!