You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WCF中IDispatchMessageInspector如何修复传入的错误XML?

Solution for Invalid XML in WCF Request Body

Your error occurs because the incoming request contains an invalid XML structure: an XML declaration (<?xml version="1.0" encoding="utf-8"?>) nested inside a <data> element, which violates XML standards. Since you can't modify the request source, you need to intercept and fix the message before WCF parses it.

Why Your Previous Attempts Failed

  • request.GetReaderAtBodyContents() and request.GetBody<string>() throw exceptions because they attempt to parse the invalid XML structure.
  • request.ToString() returns a formatted representation of the message, not the raw XML content, so string replacement here is unreliable.

Working Solution

Use IDispatchMessageInspector.AfterReceiveRequest (or IDispatchOperationSelector.SelectOperation since it runs earlier) to read the raw request body, fix the invalid XML, and replace the original message with a corrected version:

using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;

public class InvalidXmlFixInspector : IDispatchMessageInspector
{
    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
    {
        if (request == null || request.IsFault)
            return null;

        // Access HTTP request properties to get raw body stream
        if (request.Properties.ContainsKey(HttpRequestMessageProperty.Name))
        {
            var httpRequestProp = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name];
            Stream originalStream = httpRequestProp.GetBody();

            // Buffer the stream to read it multiple times
            MemoryStream bufferedStream = new MemoryStream();
            originalStream.CopyTo(bufferedStream);
            bufferedStream.Position = 0;

            // Determine request encoding from ContentType header
            Encoding encoding = Encoding.UTF8;
            string contentType = httpRequestProp.ContentType;
            if (!string.IsNullOrEmpty(contentType))
            {
                var charsetMatch = Regex.Match(contentType, @"charset=([^;]+)", RegexOptions.IgnoreCase);
                if (charsetMatch.Success)
                {
                    encoding = Encoding.GetEncoding(charsetMatch.Groups[1].Value);
                }
            }

            // Read raw body content
            string rawBody = new StreamReader(bufferedStream, encoding).ReadToEnd();
            bufferedStream.Position = 0;

            // Remove any embedded XML declarations (robust regex match)
            string correctedBody = Regex.Replace(rawBody, @"<\?xml\s+version=""[^""]+""\s+encoding=""[^""]+""\?>", string.Empty, RegexOptions.IgnoreCase);

            // Create corrected message stream
            using (var correctedStream = new MemoryStream(encoding.GetBytes(correctedBody)))
            {
                using (var xmlReader = XmlReader.Create(correctedStream))
                {
                    // Create new valid message
                    Message correctedMessage = Message.CreateMessage(xmlReader, int.MaxValue, request.Version);

                    // Copy all original message properties to preserve context
                    foreach (var prop in request.Properties)
                    {
                        if (!correctedMessage.Properties.ContainsKey(prop.Key))
                        {
                            correctedMessage.Properties.Add(prop.Key, prop.Value);
                        }
                    }

                    // Replace original request with corrected message
                    request = correctedMessage;
                }
            }

            // Update HTTP request property with buffered stream for other components
            httpRequestProp.SetBody(bufferedStream);
        }

        return null;
    }

    public void BeforeSendReply(ref Message reply, object correlationState)
    {
        // No action needed here
    }
}

Key Notes

  1. Buffering the Stream: Ensures we can read the request content multiple times without losing data.
  2. Encoding Handling: Uses the actual encoding specified in the request's ContentType header instead of assuming UTF-8.
  3. Robust Regex: Matches any standard XML declaration (case-insensitive, handles variations in quotes/attributes) to avoid missing edge cases.
  4. Property Copying: Preserves all original message properties (like HTTP headers) to maintain request context.

Using IDispatchOperationSelector

If you prefer to intercept the message earlier via IDispatchOperationSelector, the core logic remains identical—access the raw request stream, fix the XML, and replace the message with the corrected version.

内容的提问来源于stack exchange,提问作者zig8953

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 12:25:23