簡體   English   中英

自定義消息編碼器c#中的錯誤“找不到來自MTOM消息的Content-Type標頭”

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM