[英]Error “Content-Type header from MTOM message not found” in custom message encoder c#
I have a client application in C# that needs to consume a third party web service coded in Java, and the response is MTOM. 我在C#中有一个客户端应用程序,需要使用Java编码的第三方Web服务,并且响应是MTOM。 When I uses native message encoder and configure basicHttpBinding, I receivced error "the content length of charset element...".
当我使用本机消息编码器并配置basicHttpBinding时,收到错误“字符集元素的内容长度...”。 Well, the third party service (or the web server container) is not sending the charset, so I decided to create a custom message encoder and custom binding for to capture the response from web server, adds missing charset and send to application layer, but when i process the message I added charset, I received an error "Content-Type header from MTOM message not found".
好了,第三方服务(或Web服务器容器)没有发送字符集,因此我决定创建一个自定义消息编码器和自定义绑定,以捕获来自Web服务器的响应,添加缺少的字符集并发送到应用程序层,但是当我处理添加字符集的消息时,收到错误消息“找不到MTOM消息中的Content-Type标头”。
Here is what I maded: 这是我所做的:
First, I have created some classes to work with message: 首先,我创建了一些用于处理消息的类:
- CustomMtomBindingElementExtensionElement extending BindingElementExtensionElement -CustomMtomBindingElementExtensionElement扩展BindingElementExtensionElement
- CustomMtomMessageEncodingBindingElement extending MessageEncodingBindingElement and implementing IWsdlExportExtension -CustomMtomMessageEncodingBindingElement扩展MessageEncodingBindingElement并实现IWsdlExportExtension
- CustomMtomMessageEncoderFactory extending MessageEncoderFactory -CustomMtomMessageEncoderFactory扩展MessageEncoderFactory
- CustomMtomMessageEncoder extending MessageEncoder -CustomMtomMessageEncoder扩展MessageEncoder
In CustomMtomMessageEncoder i have a private attributte used to process the modified message after add charset: 在CustomMtomMessageEncoder中,我有一个私有属性,用于在添加字符集后处理修改后的消息:
public class CustomMtomMessageEncoder : MessageEncoder
{
private MessageEncoder mtomEncoder;
private CustomMtomMessageEncoderFactory factory;
private XmlWriterSettings writerSettings;
private string contentType;
public CustomMtomMessageEncoder(CustomMtomMessageEncoderFactory factory)
{
this.factory = factory;
this.writerSettings = new XmlWriterSettings();
this.contentType = string.Format("{0}; charset={1}", this.factory.MediaType, this.writerSettings.Encoding.HeaderName);
MtomMessageEncodingBindingElement mtomBindingElement = new MtomMessageEncodingBindingElement(this.MessageVersion, Encoding.GetEncoding(this.factory.CharSet));
this.factory.ReaderQuotas.CopyTo(mtomBindingElement.ReaderQuotas);
this.mtomEncoder = mtomBindingElement.CreateMessageEncoderFactory().Encoder;
}
//Other things...
}
In same class, i overrides ReadMessage method: 在同一个类中,我重写ReadMessage方法:
public override Message ReadMessage(ArraySegment<byte> buffer, BufferManager bufferManager, string contentType)
{
//Convert the received buffer into a string
byte[] incomingResponse = buffer.Array;
//read the first 500 bytes of the response
string strFirst500 = System.Text.Encoding.UTF8.GetString(incomingResponse, 0, 500);
//Check the last occurance of 'application/xop+xml' in the response. We check for the last
//occurrence since the first one is present in the Content-Type HTTP Header. Once found,
//append charset header to this string
int appIndex = strFirst500.LastIndexOf("application/xop+xml");
string modifiedResponse = strFirst500.Insert(appIndex + 19, "charset=utf-8");
modifiedResponse = modifiedResponse.Replace("application/xop+xmlcharset=utf-8", "application/xop+xml; charset=utf-8");
//convert the modified string back into a byte array
byte[] ma = System.Text.Encoding.UTF8.GetBytes(modifiedResponse);
//integrate the modified byte array back to the original byte array
int increasedLength = ma.Length - 500;
byte[] newArray = new byte[incomingResponse.Length + increasedLength];
for (int count = 0; count < newArray.Length; count++)
{
if (count < ma.Length)
{
newArray[count] = ma[count];
}
else
{
newArray[count] = incomingResponse[count - increasedLength];
}
}
//In this part generate a new ArraySegment<byte> buffer and pass it to the underlying MTOM Encoder.
ArraySegment<byte> newBuffer = new ArraySegment<byte>(newArray);
/*##### Here the error is triggered with message "can not create mtom reader for message" and inner exception is "Content-Type header from mtom message not found" #####*/
Message mensagem = this.mtomEncoder.ReadMessage(newBuffer, bufferManager);
return mensagem;
}
The error occurs in indicated line "Message mensagem = this.mtomEncoder.ReadMessage(newBuffer, bufferManager);" 错误发生在指示的行“消息mensagem = this.mtomEncoder.ReadMessage(newBuffer,bufferManager);”中
Please help. 请帮忙。
Thanks, 谢谢,
Luciano Nery 卢西亚诺·纳里(Luciano Nery)
The solution to this is to append the content type (which is part of ReadMessage parameters) to the beginning of the byte array before calling InnerEncoder.ReadMessage. 解决方案是在调用InnerEncoder.ReadMessage之前,将内容类型(属于ReadMessage参数的一部分)附加到字节数组的开头。 This is Microsoft WCF not complying with SOAP standards.
这是Microsoft WCF不符合SOAP标准。 Mind that I'm using VS2015.
请注意,我正在使用VS2015。 bytesToEncode is the buffer.Array.
bytesToEncode是buffer.Array。
const string ContentTypeHeader = "content-type";
var encoding = new UTF8Encoding(false);
var header = $"{ContentTypeHeader}: {headerValue}{Environment.NewLine}";
var headerBytes = encoding.GetBytes(header);
var contentWithHeader = new byte[headerBytes.Length + bytesToEncode.Length];
Buffer.BlockCopy(headerBytes, 0, contentWithHeader, 0, headerBytes.Length);
Buffer.BlockCopy(bytesToEncode, 0, contentWithHeader, headerBytes.Length, bytesToEncode.Length);
return contentWithHeader;
This question is very old, but still i'd like to answer it, because there might be some more ppl looking for an answer: 这个问题很老,但是我仍然想回答,因为可能会有更多的人在寻找答案:
You need to pass the contentType string to the mtomEncoder.ReadMessage function. 您需要将contentType字符串传递给mtomEncoder.ReadMessage函数。 Than it will work.
比它会工作。
In case you changed more in your ReadMessage function you might have to change the same things in the contentTypestring - but dont worry, you will receive a clean exception which will help you to fix your problem. 如果您在ReadMessage函数中进行了更多更改,则可能必须更改contentTypestring中的相同内容-但不用担心,您将收到一个干净的异常,它将帮助您解决问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.