[英]Error “Content-Type header from MTOM message not found” in custom message encoder c#
我在C#中有一个客户端应用程序,需要使用Java编码的第三方Web服务,并且响应是MTOM。 当我使用本机消息编码器并配置basicHttpBinding时,收到错误“字符集元素的内容长度...”。 好了,第三方服务(或Web服务器容器)没有发送字符集,因此我决定创建一个自定义消息编码器和自定义绑定,以捕获来自Web服务器的响应,添加缺少的字符集并发送到应用程序层,但是当我处理添加字符集的消息时,收到错误消息“找不到MTOM消息中的Content-Type标头”。
这是我所做的:
首先,我创建了一些用于处理消息的类:
-CustomMtomBindingElementExtensionElement扩展BindingElementExtensionElement
-CustomMtomMessageEncodingBindingElement扩展MessageEncodingBindingElement并实现IWsdlExportExtension
-CustomMtomMessageEncoderFactory扩展MessageEncoderFactory
-CustomMtomMessageEncoder扩展MessageEncoder
在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...
}
在同一个类中,我重写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;
}
错误发生在指示的行“消息mensagem = this.mtomEncoder.ReadMessage(newBuffer,bufferManager);”中
请帮忙。
谢谢,
卢西亚诺·纳里(Luciano Nery)
解决方案是在调用InnerEncoder.ReadMessage之前,将内容类型(属于ReadMessage参数的一部分)附加到字节数组的开头。 这是Microsoft WCF不符合SOAP标准。 请注意,我正在使用VS2015。 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;
这个问题很老,但是我仍然想回答,因为可能会有更多的人在寻找答案:
您需要将contentType字符串传递给mtomEncoder.ReadMessage函数。 比它会工作。
如果您在ReadMessage函数中进行了更多更改,则可能必须更改contentTypestring中的相同内容-但不用担心,您将收到一个干净的异常,它将帮助您解决问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.