XmlFormatExtensionAttribute 类

定义

指定服务说明格式扩展在一个或多个扩展点运行。Specifies that a service description format extension runs at one or more extension points. 此类不能被继承。This class cannot be inherited.

public ref class XmlFormatExtensionAttribute sealed : Attribute
[System.AttributeUsage(System.AttributeTargets.Class)]
public sealed class XmlFormatExtensionAttribute : Attribute
[System.AttributeUsage(System.AttributeTargets.Class, Inherited=true)]
public sealed class XmlFormatExtensionAttribute : Attribute
[<System.AttributeUsage(System.AttributeTargets.Class)>]
type XmlFormatExtensionAttribute = class
    inherit Attribute
[<System.AttributeUsage(System.AttributeTargets.Class, Inherited=true)>]
type XmlFormatExtensionAttribute = class
    inherit Attribute
Public NotInheritable Class XmlFormatExtensionAttribute
Inherits Attribute
继承
XmlFormatExtensionAttribute
属性

示例

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

注解

服务说明格式扩展扩展了如何为使用 ASP.NET 创建的 XML Web service 生成服务说明。A service description format extension extends how a service description is generated for an XML Web service created using ASP.NET. 具体来说,服务说明格式扩展将 XML 元素添加到服务说明中。Specifically, a service description format extension adds XML elements to the service description. 当 SOAP 扩展构建为在 XML Web service 的客户端和服务器端运行时,这非常有用,因为有关 SOAP 扩展的信息不会放置在服务说明中。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. 如果要将有关 SOAP 扩展的信息添加到服务说明中,客户端可以解释它必须运行特定的 SOAP 扩展。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. 必须在客户端和服务器上同时运行的 SOAP 扩展的一个示例是加密 SOAP 扩展。An example of a SOAP extension that must run on both the client and server is an encryption SOAP extension. 如果加密 SOAP 扩展仅在服务器上运行并且它在将返回值发送回客户端之前对其进行加密,则客户端必须运行 SOAP 扩展来解密 SOAP 消息。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. 生成一个从派生的类 ServiceDescriptionFormatExtensionBuild a class that derives from ServiceDescriptionFormatExtension.

  2. 将应用 XmlFormatExtensionAttribute 到类,并指定应在其上运行服务说明格式扩展的扩展点。Apply a XmlFormatExtensionAttribute to the class and specify the extension points at which the service description format extension should run.

  3. (可选)将应用于 XmlFormatExtensionPointAttribute 类,并指定类中充当新扩展点的成员。Optionally, apply a XmlFormatExtensionPointAttribute to the class and specify a member within the class that acts as a new extension point.

  4. (可选)将应用 XmlFormatExtensionPrefixAttribute 到类,并指定要与服务说明格式扩展生成的 xml 元素关联的 xml 命名空间前缀。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. 在配置文件的节中配置要运行的服务说明格式扩展 serviceDescriptionFormatExtensionTypesConfigure the service description format extension to run within the serviceDescriptionFormatExtensionTypes section of the configuration file.

构造函数

XmlFormatExtensionAttribute()

初始化 XmlFormatExtensionAttribute 类的新实例。Initializes a new instance of the XmlFormatExtensionAttribute class.

XmlFormatExtensionAttribute(String, String, Type)

初始化 XmlFormatExtensionAttribute 类的新实例,指定在指定的扩展点处运行时要添加的 XML 元素和命名空间。Initializes a new instance of the XmlFormatExtensionAttribute class that specifies the XML element and namespace to add when running at the specified extension point.

XmlFormatExtensionAttribute(String, String, Type, Type)

初始化 XmlFormatExtensionAttribute 类的新实例,指定在指定的扩展点处运行时要添加的 XML 元素和命名空间。Initializes a new instance of the XmlFormatExtensionAttribute class that specifies the XML element and namespace to add when running at the specified extension points.

XmlFormatExtensionAttribute(String, String, Type, Type, Type)

初始化 XmlFormatExtensionAttribute 类的新实例,指定在指定的扩展点处运行时要添加的 XML 元素和命名空间。Initializes a new instance of the XmlFormatExtensionAttribute class that specifies the XML element and namespace to add when running at the specified extension points.

XmlFormatExtensionAttribute(String, String, Type, Type, Type, Type)

初始化 XmlFormatExtensionAttribute 类的新实例,指定在指定的扩展点处运行时要添加的 XML 元素和命名空间。Initializes a new instance of the XmlFormatExtensionAttribute class that specifies the XML element and namespace to add when running at the specified extension points.

XmlFormatExtensionAttribute(String, String, Type[])

初始化 XmlFormatExtensionAttribute 类的新实例,指定在指定的扩展点处运行时要添加的 XML 元素和命名空间。Initializes a new instance of the XmlFormatExtensionAttribute class that specifies the XML element and namespace to add when running at the specified extension points.

属性

ElementName

获取或设置由服务说明格式扩展添加到服务说明中的 XML 元素。Gets or sets the XML element added to the service description by the service description format extension.

ExtensionPoints

服务说明格式扩展要运行的步骤。The stages at which the service description format extension is to run.

Namespace

获取或设置由服务说明格式扩展添加到服务说明的 XML 元素的 XML 命名空间。Gets or sets the XML namespace for the XML element added to the service description by the service description format extension.

TypeId

在派生类中实现时,获取此 Attribute 的唯一标识符。When implemented in a derived class, gets a unique identifier for this Attribute.

(继承自 Attribute)

方法

Equals(Object)

返回一个值,该值指示此实例是否与指定的对象相等。Returns a value that indicates whether this instance is equal to a specified object.

(继承自 Attribute)
GetHashCode()

返回此实例的哈希代码。Returns the hash code for this instance.

(继承自 Attribute)
GetType()

获取当前实例的 TypeGets the Type of the current instance.

(继承自 Object)
IsDefaultAttribute()

在派生类中重写时,指示此实例的值是否是派生类的默认值。When overridden in a derived class, indicates whether the value of this instance is the default value for the derived class.

(继承自 Attribute)
Match(Object)

当在派生类中重写时,返回一个指示此实例是否等于指定对象的值。When overridden in a derived class, returns a value that indicates whether this instance equals a specified object.

(继承自 Attribute)
MemberwiseClone()

创建当前 Object 的浅表副本。Creates a shallow copy of the current Object.

(继承自 Object)
ToString()

返回表示当前对象的字符串。Returns a string that represents the current object.

(继承自 Object)

显式接口实现

_Attribute.GetIDsOfNames(Guid, IntPtr, UInt32, UInt32, IntPtr)

将一组名称映射为对应的一组调度标识符。Maps a set of names to a corresponding set of dispatch identifiers.

(继承自 Attribute)
_Attribute.GetTypeInfo(UInt32, UInt32, IntPtr)

检索对象的类型信息,然后可以使用该信息获取接口的类型信息。Retrieves the type information for an object, which can be used to get the type information for an interface.

(继承自 Attribute)
_Attribute.GetTypeInfoCount(UInt32)

检索对象提供的类型信息接口的数量(0 或 1)。Retrieves the number of type information interfaces that an object provides (either 0 or 1).

(继承自 Attribute)
_Attribute.Invoke(UInt32, Guid, UInt32, Int16, IntPtr, IntPtr, IntPtr, IntPtr)

提供对某一对象公开的属性和方法的访问。Provides access to properties and methods exposed by an object.

(继承自 Attribute)

适用于

另请参阅