I know it is an old post but I faced the same issue recently. And some response links are no longer available.
For me, the problem was caused because the server responded with ISO-8859-1 but my Client accepts UTF-8 by default.
The solution was to create a CustomTextMessageBindingElement that matches with the server configs:
public class CustomTextMessageBindingElement : MessageEncodingBindingElement
{
public override MessageVersion MessageVersion { get; set; }
public string MediaType { get; set; }
public string Encoding { get; set; }
CustomTextMessageBindingElement(CustomTextMessageBindingElement binding)
: this(binding.Encoding, binding.MediaType, binding.MessageVersion)
{
}
public CustomTextMessageBindingElement(string encoding, string mediaType,
MessageVersion messageVersion)
{
this.MessageVersion = messageVersion;
this.MediaType = mediaType;
this.Encoding = encoding;
}
public CustomTextMessageBindingElement(string encoding, MessageVersion messageVersion)
{
this.Encoding = encoding;
this.MessageVersion = messageVersion;
if (messageVersion.Envelope == EnvelopeVersion.Soap11)
{
this.MediaType = "text/xml";
}
else if (messageVersion.Envelope == EnvelopeVersion.Soap12)
{
this.MediaType = "application/soap+xml";
}
else
{
this.MediaType = "application/xml";
}
}
public override BindingElement Clone()
{
return new CustomTextMessageBindingElement(this);
}
public override MessageEncoderFactory CreateMessageEncoderFactory()
{
return new CustomTextMessageEncoderFactory(MediaType, Encoding, MessageVersion);
}
public override IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
context.BindingParameters.Add(this);
return context.BuildInnerChannelFactory<TChannel>();
}
}
public class CustomTextMessageEncoder : MessageEncoder
{
private CustomTextMessageEncoderFactory factory;
private XmlWriterSettings writerSettings;
private string contentType;
public CustomTextMessageEncoder(CustomTextMessageEncoderFactory factory)
{
this.factory = factory;
this.writerSettings = new XmlWriterSettings();
this.writerSettings.Encoding = Encoding.GetEncoding(factory.CharSet);
this.contentType = string.Format("{0}; charset={1}",
this.factory.MediaType, this.writerSettings.Encoding.HeaderName);
}
public override bool IsContentTypeSupported(string contentType)
{
return true;
}
public override string ContentType
{
get
{
return this.contentType;
}
}
public override string MediaType
{
get
{
return factory.MediaType;
}
}
public override MessageVersion MessageVersion
{
get
{
return 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)
{
this.version = version;
this.mediaType = mediaType;
this.charSet = charSet;
this.encoder = new CustomTextMessageEncoder(this);
}
public override MessageEncoder Encoder
{
get
{
return this.encoder;
}
}
public override MessageVersion MessageVersion
{
get
{
return this.version;
}
}
internal string MediaType
{
get
{
return this.mediaType;
}
}
internal string CharSet
{
get
{
return this.charSet;
}
}
}
And then create a CustomBinding that use the CustomTextMessageBindingElement:
private Binding GetBindConfiguration()
{
//This configs could be different in Soap server that you are implementing
//set the soap server config: encoding, mediaType and Soap Version 1.1
var custom = new CustomTextMessageBindingElement("ISO-8859-1", "text/xml", MessageVersion.CreateVersion(EnvelopeVersion.Soap11, AddressingVersion.None));
var httpsBindingElement = new HttpsTransportBindingElement()
{
MaxReceivedMessageSize = int.MaxValue,
};
return new CustomBinding(custom, httpsBindingElement);
}
Finaly use the CustomBinding:
//Auto generated class using svcutil tool
var clientSoap = new WebService_SigISSPortTypeClient(GetBindConfiguration(), new EndpointAddress(new Uri("https://serverAddress.com.br")));
I believe that this solution, should work for .net core too with little changes and using the new dotnet-svcutil tool
References:
Implementation of CustomTextMessageEncodingBindingElement
Docs for Message Encoder Extensibility