次の方法で共有


XmlFormatExtensionAttribute クラス

サービス記述形式拡張機能を 1 つ以上の拡張ポイントで実行することを指定します。このクラスは継承できません。

この型のすべてのメンバの一覧については、XmlFormatExtensionAttribute メンバ を参照してください。

System.Object
   System.Attribute
      System.Web.Services.Configuration.XmlFormatExtensionAttribute

<AttributeUsage(AttributeTargets.Class)>
NotInheritable Public Class XmlFormatExtensionAttribute   Inherits Attribute
[C#]
[AttributeUsage(AttributeTargets.Class)]
public sealed class XmlFormatExtensionAttribute : Attribute
[C++]
[AttributeUsage(AttributeTargets::Class)]
public __gc __sealed class XmlFormatExtensionAttribute : public   Attribute
[JScript]
public
   AttributeUsage(AttributeTargets.Class)
class XmlFormatExtensionAttribute extends Attribute

スレッドセーフ

この型の public static (Visual Basicでは Shared) のすべてのメンバは、マルチスレッド操作で安全に使用できます。インスタンスのメンバの場合は、スレッドセーフであるとは限りません。

解説

サービス記述形式拡張機能は、ASP.NET を使用して作成した XML Web サービスに関するサービスの説明を生成する方法について、機能を拡張します。具体的には、サービス記述形式拡張機能によって、サービスの説明に XML 要素が追加されます。SOAP 拡張機能に関する情報はサービスの説明に含まれないため、SOAP 拡張機能を XML Web サービスのクライアント側とサーバー側の両方で実行できるように構築する場合には、この機能が役に立ちます。このため、SOAP 拡張機能に関する情報をサービスの説明に追加すると、クライアントは特定の SOAP 拡張機能を実行する必要があると解釈します。クライアントとサーバーの両方で実行する必要のある SOAP 拡張機能の例には、暗号化 SOAP 拡張機能があります。暗号化 SOAP 拡張機能がサーバー上だけで実行されていて、戻り値を暗号化してからクライアントに返信する場合、クライアントは SOAP 拡張機能を実行して SOAP メッセージを復号化する必要があります。そうでない場合は、クライアントで戻り値を処理することはできません。

サービス記述形式拡張機能を構築するには、次の手順を実行する必要があります。

  1. ServiceDescriptionFormatExtension から派生するクラスを構築します。
  2. サービス記述形式拡張機能が実行される拡張ポイントを指定して、 XmlFormatExtensionAttribute をクラスに適用します。
  3. クラス内のメンバが新しい拡張ポイントとして機能することをオプションで指定して、 XmlFormatExtensionPointAttribute をクラスに適用します。
  4. オプションで、XML 名前空間プリフィックスをサービス記述形式拡張機能によって生成された XML 要素に関連付けるように指定して、 XmlFormatExtensionPrefixAttribute をクラスに適用します。
  5. 構成ファイルの serviceDescriptionFormatExtensionTypes セクションで実行する、サービス記述形式拡張機能を設定します。

使用例

 
Imports System
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.
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.
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 = "https://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

[C#] 
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, as 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 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.
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 = "https://www.contoso.com/yml";

    [XmlElement("Reverse")]
    public Boolean Reverse 
    {
        get { return reverse; }
        set { reverse = value; }
    }
}

[C++] 
#using <mscorlib.dll>
#using <System.dll>
#using <System.Web.Services.dll>
#using <System.Xml.dll>
using namespace System;
using namespace System::CodeDom;
using namespace System::IO;
using namespace System::Text;
using namespace System::Web::Services::Configuration;
using namespace System::Web::Services::Description;
using namespace System::Web::Services::Protocols;
using namespace System::Xml::Serialization;

public __gc class YMLExtension;

// 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 __gc class YMLAttribute : public SoapExtensionAttribute
{
    int priority;
    bool disabled;

public:
    YMLAttribute() : disabled(false) {
        priority = 0;
        disabled = false;
    }

    YMLAttribute(bool disabled) {
        this->disabled = disabled;
    }

    __property Type* get_ExtensionType() { return __typeof(YMLExtension); }

    __property int get_Priority() { return priority; }
    __property void set_Priority(int value) { priority = value; }

    __property bool get_Disabled() { return disabled; }
    __property void set_Disabled(bool value) { disabled = value; }

};


public __gc class YMLExtension : public SoapExtension {
    bool disabled;
    Stream* oldStream;
    Stream* newStream;

public:
    YMLExtension()
    {
        disabled = false;
    }

    Object* GetInitializer(LogicalMethodInfo* /*methodInfo*/, SoapExtensionAttribute* attribute) {
        YMLAttribute* attr = dynamic_cast<YMLAttribute*>(attribute);
        if (attr != 0) 
            return __box(attr->get_Disabled());
        return __box(false);
    }

    Object* GetInitializer(Type* /*serviceType*/) {
        return __box(false);
    }

    void Initialize(Object* initializer) {
        if (Boolean * pb = dynamic_cast<System::Boolean*>(initializer)) 
            disabled = *pb;
    }

    Stream* ChainStream(Stream* stream) {
        if (disabled) return __super::ChainStream(stream);
        oldStream = stream;
        newStream = new MemoryStream();
        return newStream;
    }

    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 = S"text/yml";
    }

    void Decode(SoapMessage* message) {
        if (String::Compare(message->ContentType, S"text/yml") != 0) 
            throw new Exception(String::Concat(S"invalid content type: {0}",message->ContentType));
        Reverse(oldStream, newStream);
        newStream->Position = 0;
        message->ContentType = S"text/xml";
    }

    void Reverse(Stream* from, Stream* to) {
        TextReader* reader = new StreamReader(from);
        TextWriter* writer = new StreamWriter(to);
        String* line;
        while ((line = reader->ReadLine()) != 0) {
            StringBuilder* builder = new StringBuilder();
            for (int i = line->Length - 1; i >= 0; i--) {
                builder->Append(line->Chars[i]);
            }
            writer->WriteLine(builder);
        }
        writer->Flush();
    }
};


// The YMLOperationBinding class is part of the YML SDFE, as it is the
// class that gets serialized into XML and gets placed in the service
// description.
[XmlFormatExtension(S"action", S"YMLOperationBinding::YMLNamespace", __typeof(OperationBinding))]
[XmlFormatExtensionPrefix(S"yml", S"YMLOperationBinding::YMLNamespace")]
public __gc class YMLOperationBinding : public ServiceDescriptionFormatExtension {
private:
    Boolean reverse;

public:
    const String* YMLNamespace;
    YMLOperationBinding() : YMLNamespace(S"https://www.contoso.com/yml") {}

    [XmlElement(S"Reverse")]
    __property Boolean get_Reverse() { return reverse; }
    [XmlElement(S"Reverse")]
    __property void set_Reverse(Boolean value) { reverse = value; }
};

// The YMLReflector class is part of the YML SDFE, as it gets
// called during the service description generation process.
public __gc class YMLReflector : public SoapExtensionReflector {
public:
    void ReflectMethod() {
        ProtocolReflector *reflector = ReflectionContext;
        YMLAttribute *attr = dynamic_cast<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 != 0) {
            YMLOperationBinding* yml = new YMLOperationBinding();
            yml->Reverse = !(attr->Disabled);
            reflector->OperationBinding->Extensions->Add(yml);
        }
    }
};

// The YMLImporter class is part of the YML SDFE, as it gets called when
// a proxy class is generated for each XML Web service method the proxy class
// communictes 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 __gc class YMLImporter : public SoapExtensionImporter {
public:
    void ImportMethod(CodeAttributeDeclarationCollection *metadata) {
        SoapProtocolImporter *importer = ImportContext;
        // Check whether the XML specified in the YMLOperationBinding is in the
        // service description.
        YMLOperationBinding *yml = dynamic_cast<YMLOperationBinding*>(importer->OperationBinding->Extensions->Find(__typeof(YMLOperationBinding)));
        if (yml != 0) {
            // 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(__box(true))));
                metadata->Add(attr);
            }
        }
    }
};

[JScript] JScript のサンプルはありません。Visual Basic、C#、および C++ のサンプルを表示するには、このページの左上隅にある言語のフィルタ ボタン 言語のフィルタ をクリックします。

必要条件

名前空間: System.Web.Services.Configuration

プラットフォーム: Windows 98, Windows NT 4.0, Windows Millennium Edition, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 ファミリ

アセンブリ: System.Web.Services (System.Web.Services.dll 内)

参照

XmlFormatExtensionAttribute メンバ | System.Web.Services.Configuration 名前空間 | ServiceDescriptionFormatExtension | XmlFormatExtensionAttribute | XmlFormatExtensionPointAttribute | XmlFormatExtensionPrefixAttribute