asmx 和 wsdl_ASMX SoapExtension去除空白和换行

asmx 和 wsdl

asmx 和 wsdl

Someone asked...

有人问...

[I've got] a WebService with a WebMethod of the form.  Very Simple.

[我有一个]带有形式为WebMethod的WebService。 很简单。

[WebMethod]public XmlNode HelloWorld () {                XmlDocument document = new XmlDocument();                document.LoadXml(“<a><b><c><d>Hello World</d></c></b></a>”);                return document;}

[WebMethod] 公共XmlNode HelloWorld(){ XmlDocument文档=新的XmlDocument(); document.LoadXml(“ <​​a> <b> <c> <d> Hello World </ d> </ c> </ b> </a>”); 退还文件; }

What comes back is something in the response is something like

返回的是响应中的某些内容,例如

<a>                <b>                                <c>                                                <d>Hello World</d>                                </c>                </b></a>

<a> <b> <c> <d> Hello World </ d> </ c> </ b> </a>

Where each level of indentation is actually only 2 characters.   I would like it to come back just like it is entered in the LoadXml call [no unneeded whitespace and no unneeded new lines.]

每个缩进级别实际上只有2个字符。 我希望它回来,就像在LoadXml调用中输入的一样[不需要的空白和不需要的新行。]

This is an old problem. Basically if you look at SoapServerProtocol.GetWriterForMessage, they...

这是一个老问题。 基本上,如果您查看SoapServerProtocol.GetWriterForMessage,它们就会...

return new XmlTextWriter(new StreamWriter(message.Stream, new UTF8Encoding(false), bufferSize));

...just make one. You don't get to change the settings. Of course, in WCF this is easy, but this person was using ASMX.

...只做一个。 您无需更改设置。 当然,在WCF中这很容易,但是此人正在使用ASMX。

Enter the SoapExtension. In the web.config I'll register one.

输入SoapExtension。 在web.config中,我将注册一个。

<system.web>
    <webServices>
      <soapExtensionTypes>
        <add type="ASMXStripWhitespace.ASMXStripWhitespaceExtension, ASMXStripWhitespace"
             priority="1"
             group="High" />
      </soapExtensionTypes>
    </webServices>
...

And my class will derive from SoapExtension. There's lots of good details in this MSDN article by George Shepard a while back.

我的课程将来自SoapExtension。 乔治·谢泼德(George Shepard)MSDN上的这篇文章中有很多很好的细节。

Here's my quicky implementation. Basically we're just reading in the stream of XML that was just output by the ASMX (specifically the XmlSerializer that used that XmlTextWriter we saw above) infrastructure.

这是我的快速实现。 基本上我们只是读取XML流(即使用了XmlTextWriter的我们上面看到的具体XmlSerializer的)基础设施,只是输出由ASMX英寸

using System;
using System.IO;
using System.Web.Services.Protocols;
using System.Text;
using System.Xml;

namespace ASMXStripWhitespace
{
    public class ASMXStripWhitespaceExtension : SoapExtension
    {
        // Fields
        private Stream newStream;
        private Stream oldStream;

        public MemoryStream YankIt(Stream streamToPrefix)
        {
            streamToPrefix.Position = 0L;
            XmlTextReader reader = new XmlTextReader(streamToPrefix);

            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = false;
            settings.NewLineChars = "";
            settings.NewLineHandling = NewLineHandling.None;
            settings.Encoding = Encoding.UTF8;
            MemoryStream outStream = new MemoryStream();
            using(XmlWriter writer = XmlWriter.Create(outStream, settings))
            {
                do
                {
                    writer.WriteNode(reader, true);
                }
                while (reader.Read());
                writer.Flush();
            }
           
            debug
            //outStream.Seek(0, SeekOrigin.Begin);
            outStream.Position = 0L;
            //StreamReader reader2 = new StreamReader(outStream);
            //string s = reader2.ReadToEnd();
            //System.Diagnostics.Debug.WriteLine(s);

            //outStream.Position = 0L;
            outStream.Seek(0, SeekOrigin.Begin);
            return outStream;
        }

        // Methods
        private void StripWhitespace()
        {
            this.newStream.Position = 0L;
            this.newStream = this.YankIt(this.newStream);
            this.Copy(this.newStream, this.oldStream);
        }

        private void Copy(Stream from, Stream to)
        {
            TextReader reader = new StreamReader(from);
            TextWriter writer = new StreamWriter(to);
            writer.WriteLine(reader.ReadToEnd());
            writer.Flush();
        }

        public override void ProcessMessage(SoapMessage message)
        {
            switch (message.Stage)
            {
                case SoapMessageStage.BeforeSerialize:
                case SoapMessageStage.AfterDeserialize:
                    return;

                case SoapMessageStage.AfterSerialize:
                    this.StripWhitespace();
                    return;
                case SoapMessageStage.BeforeDeserialize:
                    this.GetReady();
                    return;
            }
            throw new Exception("invalid stage");
        }

        public override Stream ChainStream(Stream stream)
        {
            this.oldStream = stream;
            this.newStream = new MemoryStream();
            return this.newStream;
        }

        private void GetReady()
        {
            this.Copy(this.oldStream, this.newStream);
            this.newStream.Position = 0L;
        }

        public override object GetInitializer(Type t)
        {
            return typeof(ASMXStripWhitespaceExtension);
        }

        public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
        {
            return attribute;
        }

        public override void Initialize(object initializer)
        {
            //You'd usually get the attribute here and pull whatever you need off it.
            ASMXStripWhitespaceAttribute attr = initializer as ASMXStripWhitespaceAttribute;
        }
    }

    [AttributeUsage(AttributeTargets.Method)]
    public class ASMXStripWhitespaceAttribute : SoapExtensionAttribute
    {
        // Fields
        private int priority;

        // Properties
        public override Type ExtensionType
        {
            get { return typeof(ASMXStripWhitespaceExtension); }
        }

        public override int Priority
        {
            get { return this.priority; }
            set { this.priority = value;}
        }
    }
}

The order that things happen is important. The overridden call to ChainStream is where we get a new copy of the stream. The ProcessMessage switch is our opportunity to "get ready" and where we "strip whitespace."

事情发生的顺序很重要。 对ChainStream的重写调用是我们获取流的新副本的地方。 ProcessMessage开关是我们“准备”和“剥离空白”的机会。

If you want a method to use this, you have to add the attribute, in this case "ASMXStripWhitespace" to that method. Notice the attribute class just above. You can pass things into it if you like or override standard properties also.

如果要使用一种方法,则必须向该方法添加属性,在本例中为“ ASMXStripWhitespace”。 注意上面的属性类。 您可以根据需要将内容传递给它,也可以覆盖标准属性。

public class Service1 : System.Web.Services.WebService
{
   [WebMethod]
   [ASMXStripWhitespace]
   public XmlNode HelloWorld () {
         XmlDocument document = new XmlDocument();
         document.LoadXml("<a><b><c><d>Hello World</d></c></b></a>");
         return document;
   }
}

The real work happens in YankIt where we just setup our own XmlSerializer and spin through the reader and writing out to the memory stream using the new settings of no new line chars and no indentation. Notice that the reader.Read() is a Do/While and not just a While. We don't want to lose the root node.

真正的工作发生在YankIt中,我们只需要设置我们自己的XmlSerializer并旋转读取器,并使用没有换行符和缩进的新设置来写出内存流。 请注意,reader.Read()是一个Do / While,而不仅仅是While。 我们不想丢失根节点。

翻译自: https://www.hanselman.com/blog/asmx-soapextension-to-strip-out-whitespace-and-new-lines

asmx 和 wsdl

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值