zoukankan      html  css  js  c++  java
  • wcf/web service 编码

    using System;
    using System.CodeDom;
    using System.IO;
    using System.Text;
    using System.Web.Services.Configuration;
    using System.Web.Services.Description;
    using System.Web.Services.Protocols;
    using System.Xml.Serialization;
     
    // The YMLAttribute allows a developer to specify that the YML SOAP
    // extension run on a per-method basis.  The disabled property
    // turns reversing the XML on and off. 
    
    [AttributeUsage(AttributeTargets.Method, AllowMultiple=false)]
    public class YMLAttribute : SoapExtensionAttribute 
    {
      int priority = 0;
      bool disabled = false;
           
      public YMLAttribute() : this(false) {}
      public YMLAttribute(bool disabled) 
      {
         this.disabled = disabled;
      }
          
      public override Type ExtensionType 
      {
        get { return typeof(YMLExtension); }
      }
      public override int Priority 
      {
        get { return priority; }
        set { priority = value; }
      }
    
      public bool Disabled 
      { 
        get { return disabled; }
        set { disabled = value; }
      }
    }
    
    public class YMLExtension : SoapExtension 
    {
      bool disabled = false;
      Stream oldStream;
      Stream newStream;
    
      public override object GetInitializer(LogicalMethodInfo methodInfo,
                                            SoapExtensionAttribute attribute)
      {
        YMLAttribute attr = attribute as YMLAttribute;
        if (attr != null) return attr.Disabled;
           return false;
      }
    
      public override object GetInitializer(Type serviceType) 
      {
            return false;
      }
    
      public override void Initialize(object initializer) 
      {
         if (initializer is Boolean) disabled = (bool)initializer;
      }
    
      public override Stream ChainStream(Stream stream) 
      {
         if (disabled) return base.ChainStream(stream);
         oldStream = stream;
         newStream = new MemoryStream();
         return newStream;
      }
    
      public override void ProcessMessage(SoapMessage message) 
      {
        if (disabled) return;
        switch (message.Stage) 
        {
          case SoapMessageStage.BeforeSerialize:
            Encode(message);
            break;
          case SoapMessageStage.AfterSerialize:
            newStream.Position = 0;
            Reverse(newStream, oldStream);
            break;
          case SoapMessageStage.BeforeDeserialize:
            Decode(message);
            break;
          case SoapMessageStage.AfterDeserialize:
            break;
        }
      }        
      void Encode(SoapMessage message) 
      {
         message.ContentType = "text/yml";
      }
    
      void Decode(SoapMessage message) 
      {
       if (message.ContentType != "text/yml") 
         throw new Exception("invalid content type:" + message.ContentType);
       Reverse(oldStream, newStream);
       newStream.Position = 0;
       message.ContentType = "text/xml";
      }
    
      void Reverse(Stream from, Stream to) 
      {
        TextReader reader = new StreamReader(from);
        TextWriter writer = new StreamWriter(to);
        string line;
        while ((line = reader.ReadLine()) != null) 
        {
          StringBuilder builder = new StringBuilder();
          for (int i = line.Length - 1; i >= 0; i--) 
          {
            builder.Append(line[i]);
          }
          writer.WriteLine(builder.ToString());
        }
        writer.Flush();
      }
    }
    
    // The YMLReflector class is part of the YML SDFE; it is
    // called during the service description generation process.
    public class YMLReflector : SoapExtensionReflector 
    {
      public override void ReflectMethod() 
      {
        ProtocolReflector reflector = ReflectionContext;
        YMLAttribute attr = (YMLAttribute)reflector.Method.GetCustomAttribute(
                            typeof(YMLAttribute));
        // If the YMLAttribute has been applied to this Web service
        // method, adds the XML defined in the YMLOperationBinding class.
        if (attr != null) 
        {
          YMLOperationBinding yml = new YMLOperationBinding();
          yml.Reverse = !(attr.Disabled);
          reflector.OperationBinding.Extensions.Add(yml);
        }
      }
    }
      
    // The YMLImporter class is part of the YML SDFE; it is called when
    // a proxy class is generated for each Web service method the proxy
    // class communicates with.  The class checks whether the service
    // description contains the XML that this SDFE adds to a service
    // description.  If it exists, then the YMLExtension is applied to the
    // method in the proxy class.
    public class YMLImporter : SoapExtensionImporter 
    {
      public override void ImportMethod(CodeAttributeDeclarationCollection
                                        metadata)
     {
        SoapProtocolImporter importer = ImportContext;
       // Checks whether the XML specified in the YMLOperationBinding is in
       // the service description.
       YMLOperationBinding yml = (YMLOperationBinding)
           importer.OperationBinding.Extensions.Find(
           typeof(YMLOperationBinding));
       if (yml != null)
       {
         // Only applies the YMLAttribute to the method when the XML should
         // be reversed.
         if (yml.Reverse)
         {
           CodeAttributeDeclaration attr = new CodeAttributeDeclaration(
                typeof(YMLAttribute).FullName);
           attr.Arguments.Add(new CodeAttributeArgument(new
             CodePrimitiveExpression(true)));
           metadata.Add(attr);
         }
       }
     }
    }
    
    // The YMLOperationBinding class is part of the YML SDFE; it is the
    // class that is serialized into XML and placed in the service
    // description.
    [XmlFormatExtension("action", YMLOperationBinding.YMLNamespace,
                        typeof(OperationBinding))]
    [XmlFormatExtensionPrefix("yml", YMLOperationBinding.YMLNamespace)]
    public class YMLOperationBinding : ServiceDescriptionFormatExtension 
    {
       private Boolean reverse;
       public const string YMLNamespace = "http://www.contoso.com/yml";
    
       [XmlElement("Reverse")]
       public Boolean Reverse 
       {
         get { return reverse; }
         set { reverse = value; }
       }
    }
    
  • 相关阅读:
    开发错误记录2 .MainActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
    开发错误记录1:解决:Only the original thread that created a view hierarchy can touch its views.
    第二篇 Python初识别及变量名定义规范
    第三篇 Python执行方式和变量初始
    第一篇 Python安装与环境变量的配置
    1. Linux系统常用操作
    Python的内存管理、命名规则、3个特性讲解
    操作系统及Python解释器工作原理讲解
    计算机基础小白篇
    Oracle SQL性能优化
  • 原文地址:https://www.cnblogs.com/encounter/p/2188794.html
Copyright © 2011-2022 走看看