SimonPrice3376
asked on
XML Encoding not in WCF Response
I am working in a company where we are taking over the provision of a service, but writing is ourselves rather than having access to the original source code and need to match the output character for character so that this doesnt cause our clients any issues.
When sending an error response back it must have the xml encoding at the top as per the response below
I get everything but this
My code currently looks like this
This is the rest of the code for ErrorMessageFormatter and the Factory
I would be grateful for some help on why the XML encoding and version inforamation are not coming through and how I can resolve this.
When sending an error response back it must have the xml encoding at the top as per the response below
<?xml version="1.0" encoding="UTF-8"?>
<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>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Client</faultcode>
<faultstring>HstException: The hash supplied does not match the hash generated for string:1234512312321</faultstring>
<faultactor>{faultFactorHere}</faultactor>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
I get everything but this
<?xml version="1.0" encoding="UTF-8"?>
My code currently looks like this
public void ProvideFault(Exception error, MessageVersion messageVersion, ref Message fault)
{
var faultException = new FaultException(error.Message);
var messageFault = faultException.CreateMessageFault();
var message = Message.CreateMessage(messageVersion, messageFault, null);
var newMessageFormat = message.Properties.Encoder = new ErrorMessageFormatter(new CustomTextMessageEncoderFactory("text/xml", "UTF-8", MessageVersion.Soap11WSAddressing10));
message.Properties.Encoder = newMessageFormat; // this should be adding the encoding, however is not
fault = new ProposalMessage(message); //// This addes my prefixes and names spaces
}
This is the rest of the code for ErrorMessageFormatter and the Factory
public class ErrorMessageFormatter : MessageEncoder
{
private CustomTextMessageEncoderFactory factory;
private XmlWriterSettings writerSettings;
private string contentType;
public ErrorMessageFormatter(CustomTextMessageEncoderFactory factory)
{
this.factory = factory;
this.writerSettings = new XmlWriterSettings { Encoding = Encoding.GetEncoding(factory.CharSet) };
this.contentType = $"{this.factory.MediaType}; charset={this.writerSettings.Encoding.HeaderName}";
}
public override string ContentType => this.contentType;
public override string MediaType => factory.MediaType;
public override MessageVersion MessageVersion => this.factory.MessageVersion;
public override Message ReadMessage(ArraySegment<byte> buffer, BufferManager bufferManager, string contentType)
{
byte[] msgContents = new byte[buffer.Count];
Array.Copy(buffer.Array, buffer.Offset, msgContents, 0, msgContents.Length);
bufferManager.ReturnBuffer(buffer.Array);
MemoryStream stream = new MemoryStream(msgContents);
return ReadMessage(stream, int.MaxValue);
}
public override Message ReadMessage(Stream stream, int maxSizeOfHeaders, string contentType)
{
XmlReader reader = XmlReader.Create(stream);
return Message.CreateMessage(reader, maxSizeOfHeaders, this.MessageVersion);
}
public override ArraySegment<byte> WriteMessage(Message message, int maxMessageSize, BufferManager bufferManager, int messageOffset)
{
MemoryStream stream = new MemoryStream();
XmlWriter writer = XmlWriter.Create(stream, this.writerSettings);
message.WriteMessage(writer);
writer.Close();
byte[] messageBytes = stream.GetBuffer();
int messageLength = (int)stream.Position;
stream.Close();
int totalLength = messageLength + messageOffset;
byte[] totalBytes = bufferManager.TakeBuffer(totalLength);
Array.Copy(messageBytes, 0, totalBytes, messageOffset, messageLength);
ArraySegment<byte> byteArray = new ArraySegment<byte>(totalBytes, messageOffset, messageLength);
return byteArray;
}
public override void WriteMessage(Message message, Stream stream)
{
XmlWriter writer = XmlWriter.Create(stream, this.writerSettings);
message.WriteMessage(writer);
writer.Close();
}
}
public class CustomTextMessageEncoderFactory : MessageEncoderFactory
{
private MessageEncoder _encoder;
private MessageVersion _version;
private string _mediaType;
private string _charSet;
internal CustomTextMessageEncoderFactory(string mediaType, string charSet,
MessageVersion version)
{
_version = version;
_mediaType = mediaType;
_charSet = charSet;
_encoder = new ErrorMessageFormatter(this);
}
public override MessageEncoder Encoder => _encoder;
public override MessageVersion MessageVersion => _version;
internal string MediaType => _mediaType;
internal string CharSet => _charSet;
}
I would be grateful for some help on why the XML encoding and version inforamation are not coming through and how I can resolve this.
How do you intercept the SOAP message?
ASKER
Hi Stephan,
I have passed this onto a colleague of mine now as I have been re-directed to work on another WCF issue, and he is using a custom encoder now, which isnt a perfect fit for our needs, but is starting to get to where we need to go. Once I see the final solution I will post it here as an answer
I have passed this onto a colleague of mine now as I have been re-directed to work on another WCF issue, and he is using a custom encoder now, which isnt a perfect fit for our needs, but is starting to get to where we need to go. Once I see the final solution I will post it here as an answer
This question needs an answer!
Become an EE member today
7 DAY FREE TRIALMembers can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.