.NET Framework Class Library
XmlFormatExtensionAttribute Class

Specifies that a service description format extension runs at one or more extension points. This class cannot be inherited.

Inheritance Hierarchy
SystemObject
   SystemAttribute
    System.Web.Services.ConfigurationXmlFormatExtensionAttribute

Namespace:   System.Web.Services.Configuration
Assembly:  System.Web.Services (in System.Web.Services.dll)
Syntax
<[%$TOPIC/zb8sfzzs_en-us_VS_110_2_0_0_0_0%]([%$TOPIC/zb8sfzzs_en-us_VS_110_2_0_0_0_1%].Class)> _
Public NotInheritable Class XmlFormatExtensionAttribute _
	Inherits [%$TOPIC/zb8sfzzs_en-us_VS_110_2_0_0_0_2%]
[[%$TOPIC/zb8sfzzs_en-us_VS_110_2_0_1_0_0%]([%$TOPIC/zb8sfzzs_en-us_VS_110_2_0_1_0_1%].Class)]
public sealed class XmlFormatExtensionAttribute : [%$TOPIC/zb8sfzzs_en-us_VS_110_2_0_1_0_2%]
[[%$TOPIC/zb8sfzzs_en-us_VS_110_2_0_2_0_0%]([%$TOPIC/zb8sfzzs_en-us_VS_110_2_0_2_0_1%]::Class)]
public ref class XmlFormatExtensionAttribute sealed : public [%$TOPIC/zb8sfzzs_en-us_VS_110_2_0_2_0_2%]
[<[%$TOPIC/zb8sfzzs_en-us_VS_110_2_0_3_0_0%]>]
[<[%$TOPIC/zb8sfzzs_en-us_VS_110_2_0_3_0_1%]([%$TOPIC/zb8sfzzs_en-us_VS_110_2_0_3_0_2%].Class)>]
type XmlFormatExtensionAttribute =  
    class 
        inherit [%$TOPIC/zb8sfzzs_en-us_VS_110_2_0_3_0_3%] 
    end

The XmlFormatExtensionAttribute type exposes the following members.

Constructors
  NameDescription
Public method XmlFormatExtensionAttributeInitializes a new instance of the XmlFormatExtensionAttribute class.
Public method XmlFormatExtensionAttribute(String, String, Type)Initializes a new instance of the XmlFormatExtensionAttribute class that specifies the XML element and namespace to add when running at the specified extension point.
Public method XmlFormatExtensionAttribute(String, String, Type)Initializes a new instance of the XmlFormatExtensionAttribute class that specifies the XML element and namespace to add when running at the specified extension points.
Public method XmlFormatExtensionAttribute(String, String, Type, Type)Initializes a new instance of the XmlFormatExtensionAttribute class that specifies the XML element and namespace to add when running at the specified extension points.
Public method XmlFormatExtensionAttribute(String, String, Type, Type, Type)Initializes a new instance of the XmlFormatExtensionAttribute class that specifies the XML element and namespace to add when running at the specified extension points.
Public method XmlFormatExtensionAttribute(String, String, Type, Type, Type, Type)Initializes a new instance of the XmlFormatExtensionAttribute class that specifies the XML element and namespace to add when running at the specified extension points.
Top
Properties
  NameDescription
Public property ElementNameGets or sets the XML element added to the service description by the service description format extension.
Public property ExtensionPointsThe stages at which the service description format extension is to run.
Public property NamespaceGets or sets the XML namespace for the XML element added to the service description by the service description format extension.
Public property TypeIdWhen implemented in a derived class, gets a unique identifier for this Attribute. (Inherited from Attribute.)
Top
Methods
  NameDescription
Public method EqualsInfrastructure. Returns a value that indicates whether this instance is equal to a specified object. (Inherited from Attribute.)
Public method GetHashCodeReturns the hash code for this instance. (Inherited from Attribute.)
Public method GetTypeGets the Type of the current instance. (Inherited from Object.)
Public method IsDefaultAttributeWhen overridden in a derived class, indicates whether the value of this instance is the default value for the derived class. (Inherited from Attribute.)
Public method MatchWhen overridden in a derived class, returns a value that indicates whether this instance equals a specified object. (Inherited from Attribute.)
Public method ToStringReturns a string that represents the current object. (Inherited from Object.)
Top
Explicit Interface Implementations
  NameDescription
Explicit interface implemetation Private method _AttributeGetIDsOfNamesMaps a set of names to a corresponding set of dispatch identifiers. (Inherited from Attribute.)
Explicit interface implemetation Private method _AttributeGetTypeInfoRetrieves the type information for an object, which can be used to get the type information for an interface. (Inherited from Attribute.)
Explicit interface implemetation Private method _AttributeGetTypeInfoCountRetrieves the number of type information interfaces that an object provides (either 0 or 1). (Inherited from Attribute.)
Explicit interface implemetation Private method _AttributeInvokeProvides access to properties and methods exposed by an object. (Inherited from Attribute.)
Top
Remarks

A service description format extension extends how a service description is generated for an XML Web service created using ASP.NET. Specifically, a service description format extension adds XML elements to the service description. This is useful when a SOAP extension is built to run on both the client and server side of an XML Web service, as information about SOAP extensions is not placed in the service description. If you want to add information about the SOAP extension to the service description, a client can interpret that it must run the specific SOAP extension. An example of a SOAP extension that must run on both the client and server is an encryption SOAP extension. If an encryption SOAP extension runs only on the server and it encrypts return values before sending them back to the client, the client must have the SOAP extension running to decrypt the SOAP message. Otherwise, the client cannot process the return value.

Use the following steps to build a service description format extension:

  1. Build a class that derives from ServiceDescriptionFormatExtension.

  2. Apply a XmlFormatExtensionAttribute to the class and specify the extension points at which the service description format extension should run.

  3. Optionally, apply a XmlFormatExtensionPointAttribute to the class and specify a member within the class that acts as a new extension point.

  4. Optionally, apply a XmlFormatExtensionPrefixAttribute to the class and specify the XML namespace prefix to be associated with XML elements generated by the service description format extension.

  5. Configure the service description format extension to run within the serviceDescriptionFormatExtensionTypes section of the configuration file.

Examples
Imports System
Imports System.Security.Permissions
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.IO
Imports System.Text
Imports System.Web.Services.Configuration
Imports System.Web.Services.Description
Imports System.Xml.Serialization
Imports System.CodeDom

' 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
    Inherits SoapExtensionAttribute
    Dim _priority As Integer = 0
    Dim _disabled As Boolean = False 

    Public Sub New()
        Me.New(False)
    End Sub 

    Public Sub New(ByVal Disabled As Boolean)
        _disabled = Disabled
    End Sub 

    Public Overrides ReadOnly Property ExtensionType() As Type
        Get 
            Return GetType(YMLExtension)
        End Get 
    End Property 

    Public Overrides Property Priority() As Integer 
        Get 
            Return _priority
        End Get 
        Set(ByVal Value As Integer)
            _priority = Value
        End Set 
    End Property 

    Public Property Disabled() As Boolean 
        Get 
            Return _disabled
        End Get 
        Set(ByVal Value As Boolean)
            _disabled = Value
        End Set 
    End Property 
End Class 

Public Class YMLExtension
    Inherits SoapExtension
    Dim _disabled As Boolean = False 
    Dim oldStream As Stream
    Dim newStream As Stream

    Public Overloads Overrides Function GetInitializer( _
        ByVal methodInfo As LogicalMethodInfo, _
        ByVal attribute As SoapExtensionAttribute) As Object 

        Dim attr As YMLAttribute = attribute
        If (Not attr Is Nothing) Then 
            Return attr.Disabled
        End If 
        Return False 
    End Function 

    Public Overloads Overrides Function GetInitializer( _
        ByVal WebServiceType As Type) As Object 
        Return False 
    End Function 

    Public Overrides Sub Initialize(ByVal initializer As Object)
        If (TypeOf initializer Is Boolean) Then
            _disabled = CBool(initializer)
        End If 
    End Sub 

    Public Overrides Function ChainStream(ByVal streamref As Stream) As Stream
        If (_disabled) Then 
            Return CType(Me, SoapExtension).ChainStream(streamref)
        End If
        oldStream = streamref
        newStream = New MemoryStream()
        Return newStream
    End Function 

    Public Overrides Sub ProcessMessage(ByVal message As SoapMessage)
        If (_disabled) Then Return 
        Select Case (message.Stage)
            Case SoapMessageStage.BeforeSerialize
                Encode(message)
            Case SoapMessageStage.AfterSerialize
                newStream.Position = 0
                Reverse(newStream, oldStream)
            Case SoapMessageStage.BeforeDeserialize
                Decode(message)
            Case SoapMessageStage.AfterDeserialize
        End Select 
    End Sub 

    Sub Encode(ByRef message As SoapMessage)
        message.ContentType = "text/yml" 
    End Sub 

    Sub Decode(ByVal message As SoapMessage)
        If (message.ContentType <> "text/yml") Then 
            Throw New Exception("invalid content type:" & message.ContentType)
        End If
        Reverse(oldStream, newStream)
        newStream.Position = 0
        message.ContentType = "text/xml" 
    End Sub 

    Sub Reverse(ByVal source As Stream, ByVal dest As Stream)
        Dim reader As TextReader = New StreamReader(source)
        Dim writer As TextWriter = New StreamWriter(dest)
        Dim line As String
        line = reader.ReadLine()
        While (Not line Is Nothing)
            writer.WriteLine(StrReverse(line))
            line = reader.ReadLine()
        End While
        writer.Flush()
    End Sub 
End Class 


' The YMLReflector class is part of the YML SDFE, as it is 
' called during the service description generation process.
<PermissionSet(SecurityAction.Demand, Name:="FullTrust")> _
Public Class YMLReflector
    Inherits SoapExtensionReflector
    Public Overrides Sub ReflectMethod()
        Dim reflector As ProtocolReflector = ReflectionContext
        Dim attr As YMLAttribute = _
            reflector.Method.GetCustomAttribute(GetType(YMLAttribute))
        ' If the YMLAttribute has been applied to this XML Web service  
        ' method, add the XML defined in the YMLOperationBinding class. 
        If (Not attr Is Nothing) Then 
            Dim yml As YMLOperationBinding = New YMLOperationBinding()
            yml.Reverse = Not attr.Disabled
            reflector.OperationBinding.Extensions.Add(yml)
        End If 
    End Sub 
End Class 

' The YMLImporter class is part of the YML SDFE, as it is called when a 
' proxy class is generated for each XML 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.
<PermissionSet(SecurityAction.Demand, Name:="FullTrust")> _
Public Class YMLImporter
    Inherits SoapExtensionImporter
    Public Overrides Sub ImportMethod( _
        ByVal metadata As CodeAttributeDeclarationCollection)
        Dim importer As SoapProtocolImporter = ImportContext
        ' Check whether the XML specified in the YMLOperationBinding is  
        ' in the service description. 
        Dim yml As YMLOperationBinding = _
            importer.OperationBinding.Extensions.Find( _
            GetType(YMLOperationBinding))
        If (Not yml Is Nothing) Then 
            ' Only apply the YMLAttribute to the method when the XML  
            ' should be reversed. 
            If (yml.Reverse) Then 
                Dim attr As CodeAttributeDeclaration = _
                    New CodeAttributeDeclaration(GetType(YMLAttribute).FullName)
                attr.Arguments.Add( _
                    New CodeAttributeArgument(New CodePrimitiveExpression(True)))
                metadata.Add(attr)
            End If 
        End If 
    End Sub 
End Class 

' The YMLOperationBinding class is part of the YML SDFE, as it is the 
' class that is serialized into XML and is placed in the service 
' description.
<XmlFormatExtension("action", YMLOperationBinding.YMLNamespace, _
    GetType(OperationBinding)), _
    XmlFormatExtensionPrefix("yml", YMLOperationBinding.YMLNamespace)> _
Public Class YMLOperationBinding
    Inherits ServiceDescriptionFormatExtension
    Private _reverse As Boolean 
    Public Const YMLNamespace As String = "http://www.contoso.com/yml"

    <XmlElement("Reverse")> _
    Public Property Reverse() As Boolean 
        Get 
            Return _reverse
        End Get 
        Set(ByVal Value As Boolean)
            _reverse = Value
        End Set 
    End Property 

End Class
using System;
using System.Security.Permissions;
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, as it is 
// called during the service description generation process.
[PermissionSet(SecurityAction.Demand, Name="FullTrust")]
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 XML Web service  
        // method, add 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, as it is called when a 
// proxy class is generated for each XML 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.
[PermissionSet(SecurityAction.Demand, Name="FullTrust")]
public class YMLImporter : SoapExtensionImporter 
{
    public override void ImportMethod(
        CodeAttributeDeclarationCollection metadata) 
    {
        SoapProtocolImporter importer = ImportContext;
        // Check 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 apply 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, as it is the 
// class that is serialized into XML and is 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; }
    }
}
Version Information

.NET Framework

Supported in: 4.5, 4, 3.5, 3.0, 2.0, 1.1, 1.0

.NET Framework Client Profile

Supported in: 4, 3.5 SP1
Platforms

Windows 8.1, Windows Server 2012 R2, Windows 8, Windows Server 2012, Windows 7, Windows Vista SP2, Windows Server 2008 (Server Core Role not supported), Windows Server 2008 R2 (Server Core Role supported with SP1 or later; Itanium not supported)

The .NET Framework does not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.

Thread Safety
Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.