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; }

   }

}

你可能感兴趣的:(web Service)