【问题标题】:Decompress incoming HTTP SOAP requests in ASMX在 ASMX 中解压缩传入的 HTTP SOAP 请求
【发布时间】:2018-04-27 04:52:25
【问题描述】:

我正在尝试让 IIS 接受压缩的 SOAP/XML 请求

似乎 IIS 不支持开箱即用的压缩 HTTP 请求。任何带有Content-Encoding: gzipdeflate 的HTTP 请求都会返回HTTP 错误400。

所以我尝试通过 Global.asax 添加DelegatingHandler,如this related question 中所述:

Global.asax

protected void Application_Start()
{
    GlobalConfiguration.Configuration.MessageHandlers.Add(new DecompressionHandler());
}

但是在 ASMX 的情况下,似乎没有执行 MessageHandlers(我已经检查过,Application_Start 调用了,但是整个 WebApi 配置似乎没有效果在 ASMX 中)。

那么问题来了——如何在ASMX服务中实现SOAP请求解压?

【问题讨论】:

    标签: c# asp.net web-services asmx


    【解决方案1】:

    能够让它与SoapExtension一起工作:

    using System;
    using System.Collections.ObjectModel;
    using System.IO;
    using System.IO.Compression;
    using System.Linq;
    using System.Net.Http;
    using System.Threading.Tasks;
    using System.Web.Services.Protocols;
    
    /// <summary>
    ///   ASPX SOAP request decompression WebMethod annotation
    /// </summary>
    [AttributeUsage(AttributeTargets.Method)]
    public class CompressedRequestAttribute : SoapExtensionAttribute
    {
      public override Type ExtensionType { get { return typeof(CompressedRequestExtension); } }
      public override int Priority { get { return 0; } set { } }
    }
    
    /// <summary>
    ///   ASPX SOAP request decompression implementation
    /// </summary>
    public class CompressedRequestExtension : SoapExtension
    {
      public override object GetInitializer(Type serviceType) { return null; }
    
      public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute) { return null; }
    
      public override void Initialize(object initializer) { }
    
      Stream origStream;
      StreamDelegate wrappedStream = new StreamDelegate();
    
      public override void ProcessMessage(SoapMessage message) {
        switch (message.Stage) {
          case SoapMessageStage.BeforeDeserialize:
            if (message.ContentEncoding == "gzip") {
              wrappedStream.wrapped = new GZipStream(origStream, CompressionMode.Decompress, true);
              message.ContentEncoding = null;
            }
            else if (message.ContentEncoding == "deflate") {
              wrappedStream.wrapped = new DeflateStream(origStream, CompressionMode.Decompress, true);
              message.ContentEncoding = null;
            }
            else {
              goto default;
            }
            break;
          default:
            wrappedStream.wrapped = origStream;
            break;
        }
      }
    
      public override Stream ChainStream(Stream stream) {
        origStream = stream;
        return wrappedStream;
      }
    
    }
    
    public class StreamDelegate : Stream
    {
      public Stream wrapped;
      public override bool CanRead { get { return wrapped.CanRead; } }
      public override bool CanSeek { get { return wrapped.CanSeek; } }
      public override bool CanWrite { get { return wrapped.CanWrite; } }
      public override long Length { get { return wrapped.Length; } }
      public override long Position { get { return wrapped.Position; } set { wrapped.Position = value; } }
      public override void Flush() { wrapped.Flush(); }
      public override int Read(byte[] buffer, int offset, int count) { return wrapped.Read(buffer, offset, count); }
      public override long Seek(long offset, SeekOrigin origin) { return wrapped.Seek(offset, origin); }
      public override void SetLength(long value) { wrapped.SetLength(value); }
      public override void Write(byte[] buffer, int offset, int count) { wrapped.Write(buffer, offset, count); }
    }
    

    然后在每个WebMethod 上注释:

      [CompressedRequestAttribute]
    

    并证明它有效:

    POST /TestService/TestAction1.asmx HTTP/1.1
    Host: localhost
    Accept-Encoding: deflate, gzip
    SOAPAction: http://example.com/TestService:action1
    Content-Type: text/xml;charset=UTF-8
    Content-Encoding: gzip
    Content-Length: 321
    
    <gzipped-request>
    
    HTTP/1.1 200 OK
    Content-Type: text/xml; charset=utf-8
    Server: Microsoft-IIS/10.0
    X-AspNet-Version: 4.0.30319
    Content-Encoding: gzip
    Content-Length: 10193
    
    <gzipped-response>
    

    【讨论】:

      猜你喜欢
      • 2013-12-28
      • 1970-01-01
      • 1970-01-01
      • 2017-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-27
      相关资源
      最近更新 更多