Aracılığıyla paylaş


Özel WSDL Yayımı

WsdlDocumentation örneği aşağıdakilerin nasıl yapılacağını gösterir:

Not

Bu örnek için kurulum yordamı ve derleme yönergeleri bu konunun sonunda yer alır.

Hizmet

Bu örnekteki hizmet iki özel öznitelikle işaretlenmiştir. birincisi, oluşturucudaki bir dizeyi WsdlDocumentationAttributekabul eder ve kullanımını açıklayan bir dize ile bir sözleşme arabirimi veya işlemi sağlamak için uygulanabilir. İkincisi, WsdlParamOrReturnDocumentationAttributeişlemdeki bu değerleri açıklamak için değer veya parametre döndürmek için uygulanabilir. Aşağıdaki örnekte, ICalculatorbu öznitelikler kullanılarak açıklanan bir hizmet sözleşmesi gösterilmektedir.

// Define a service contract.
[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
// Document it.
[WsdlDocumentation("The ICalculator contract performs basic calculation services.")]
public interface ICalculator
{
    [OperationContract]
    [WsdlDocumentation("The Add operation adds two numbers and returns the result.")]
    [return:WsdlParamOrReturnDocumentation("The result of adding the two arguments together.")]
    double Add(
      [WsdlParamOrReturnDocumentation("The first value to add.")]double n1,
      [WsdlParamOrReturnDocumentation("The second value to add.")]double n2
    );

    [OperationContract]
    [WsdlDocumentation("The Subtract operation subtracts the second argument from the first.")]
    [return:WsdlParamOrReturnDocumentation("The result of the second argument subtracted from the first.")]
    double Subtract(
      [WsdlParamOrReturnDocumentation("The value from which the second is subtracted.")]double n1,
      [WsdlParamOrReturnDocumentation("The value that is subtracted from the first.")]double n2
    );

    [OperationContract]
    [WsdlDocumentation("The Multiply operation multiplies two values.")]
    [return:WsdlParamOrReturnDocumentation("The result of multiplying the first and second arguments.")]
    double Multiply(
      [WsdlParamOrReturnDocumentation("The first value to multiply.")]double n1,
      [WsdlParamOrReturnDocumentation("The second value to multiply.")]double n2
    );

    [OperationContract]
    [WsdlDocumentation("The Divide operation returns the value of the first argument divided by the second argument.")]
    [return:WsdlParamOrReturnDocumentation("The result of dividing the first argument by the second.")]
    double Divide(
      [WsdlParamOrReturnDocumentation("The numerator.")]double n1,
      [WsdlParamOrReturnDocumentation("The denominator.")]double n2
    );
}

IContractBehaviorIOperationBehaviorve WsdlDocumentationAttribute uygular, bu nedenle öznitelik örnekleri ilgili OperationDescriptionContractDescription veya hizmet açıldığında eklenir. özniteliği de uygular IWsdlExportExtension. Çağrıldığında ExportContract(WsdlExporter, WsdlContractConversionContext) , WsdlExporter meta verileri dışarı aktarmak için kullanılan ve WsdlContractConversionContext hizmet açıklaması nesnelerini içeren, dışarı aktarılan meta verilerin değiştirilmesini sağlayan parametre olarak geçirilir.

Bu örnekte, dışarı aktarma bağlam nesnesinin veya ContractDescriptionOperationDescriptionöğesine sahip olup olmadığına bağlı olarak, metin özelliği kullanılarak özniteliğinden bir açıklama ayıklanır ve aşağıdaki kodda gösterildiği gibi WSDL ek açıklama öğesine eklenir.

public void ExportContract(WsdlExporter exporter, WsdlContractConversionContext context)
{
    if (contractDescription != null)
    {
        // Inside this block it is the contract-level comment attribute.
        // This.Text returns the string for the contract attribute.
        // Set the doc element; if this isn't done first, there is no XmlElement in the
        // DocumentElement property.
        context.WsdlPortType.Documentation = string.Empty;
        // Contract comments.
        XmlDocument owner = context.WsdlPortType.DocumentationElement.OwnerDocument;
        XmlElement summaryElement = owner.CreateElement("summary");
        summaryElement.InnerText = this.Text;
        context.WsdlPortType.DocumentationElement.AppendChild(summaryElement);
    }
    else
    {
        Operation operation = context.GetOperation(operationDescription);
        if (operation != null)
        {
            // We are dealing strictly with the operation here.
            // This.Text returns the string for the operation-level attributes.
            // Set the doc element; if this isn't done first, there is no XmlElement in the
            // DocumentElement property.
            operation.Documentation = String.Empty;

            // Operation C# triple comments.
            XmlDocument owner = operation.DocumentationElement.OwnerDocument;
            XmlElement newSummaryElement = owner.CreateElement("summary");
            newSummaryElement.InnerText = this.Text;
            operation.DocumentationElement.AppendChild(newSummaryElement);
        }
    }
}

Bir işlem dışarı aktarılıyorsa örnek, parametrelerin değerlerini almak WsdlParamOrReturnDocumentationAttribute ve değerleri döndürmek için yansıma kullanır ve bunları bu işlemin WSDL ek açıklama öğelerine aşağıdaki gibi ekler.

// Get returns information
ParameterInfo returnValue = operationDescription.SyncMethod.ReturnParameter;
object[] returnAttrs = returnValue.GetCustomAttributes(typeof(WsdlParamOrReturnDocumentationAttribute), false);
if (returnAttrs.Length != 0)
{
    // <returns>text.</returns>
    XmlElement returnsElement = owner.CreateElement("returns");
    returnsElement.InnerText = ((WsdlParamOrReturnDocumentationAttribute)returnAttrs[0]).ParamComment;
    operation.DocumentationElement.AppendChild(returnsElement);
}

// Get parameter information.
ParameterInfo[] args = operationDescription.SyncMethod.GetParameters();
for (int i = 0; i < args.Length; i++)
{
    object[] docAttrs = args[i].GetCustomAttributes(typeof(WsdlParamOrReturnDocumentationAttribute), false);
    if (docAttrs.Length == 1)
    {
        // <param name="Int1">Text.</param>
        XmlElement newParamElement = owner.CreateElement("param");
        XmlAttribute paramName = owner.CreateAttribute("name");
        paramName.Value = args[i].Name;
        newParamElement.InnerText = ((WsdlParamOrReturnDocumentationAttribute)docAttrs[0]).ParamComment;
        newParamElement.Attributes.Append(paramName);
        operation.DocumentationElement.AppendChild(newParamElement);
    }
}

Örnek daha sonra aşağıdaki yapılandırma dosyasını kullanarak meta verileri standart şekilde yayımlar.

<services>
  <service
      name="Microsoft.ServiceModel.Samples.CalculatorService"
      behaviorConfiguration="CalculatorServiceBehavior">
    <!-- ICalculator is exposed at the base address provided by host: http://localhost/servicemodelsamples/service.svc  -->
    <endpoint address=""
              binding="wsHttpBinding"
              contract="Microsoft.ServiceModel.Samples.ICalculator" />
    <!-- the mex endpoint is exposed at http://localhost/servicemodelsamples/service.svc/mex -->
    <endpoint address="mex"
              binding="mexHttpBinding"
              contract="IMetadataExchange" />
  </service>
</services>

<!--For debugging purposes set the includeExceptionDetailInFaults attribute to true-->
<behaviors>
  <serviceBehaviors>
    <behavior name="CalculatorServiceBehavior">
      <serviceMetadata httpGetEnabled="True"/>
      <serviceDebug includeExceptionDetailInFaults="False" />
    </behavior>
  </serviceBehaviors>
</behaviors>

Svcutil istemcisi

Bu örnek Svcutil.exe kullanmaz. Sözleşme, generatedClient.cs dosyasında sağlanır, böylece örnekte özel WSDL içeri aktarma ve kod oluşturma gösterildikten sonra hizmet çağrılabilir. Bu örnekte aşağıdaki özel WSDL içeri aktarıcısını kullanmak için Svcutil.exe çalıştırabilir ve bu seçeneği belirterek bu örnekte kullanılan ve kitaplığa başvuran istemci yapılandırma dosyasının WsdlDocumentation.dll yolunu vererek belirtebilirsiniz/svcutilConfig. Ancak dosyasını yüklemek WsdlDocumentationImporteriçin, Svuctil.exe kitaplığı bulup yükleyebilmesi WsdlDocumentation.dll gerekir. Bu, kitaplığın genel derleme önbelleğinde, yolunda kayıtlı olduğu veya Svcutil.exe ile aynı dizinde olduğu anlamına gelir. Bunun gibi temel bir örnek için yapmanız gereken en kolay şey, Svcutil.exe ve istemci yapılandırma dosyasını ile aynı dizine WsdlDocumentation.dll kopyalamak ve oradan çalıştırmaktır.

Özel WSDL İçeri Aktarıcısı

Özel IWsdlImportExtension nesne WsdlDocumentationImporter ayrıca IContractBehaviorIOperationBehavior , içeri aktarılan ServiceEndpoint'lere eklenip eklenecek ve IServiceContractGenerationExtensionIOperationContractGenerationExtension sözleşme veya işlem kodu oluşturulurken kod oluşturma işlemini değiştirmek için çağrılır.

İlk olarak, yönteminde ImportContract(WsdlImporter, WsdlContractConversionContext) örnek, WSDL ek açıklamasının sözleşme veya işlem düzeyinde olup olmadığını belirler ve içeri aktarılan ek açıklama metnini oluşturucusunda geçirerek kendisini uygun kapsamda bir davranış olarak ekler.

public void ImportContract(WsdlImporter importer, WsdlContractConversionContext context)
{
    // Contract Documentation
    if (context.WsdlPortType.Documentation != null)
    {
        // System examines the contract behaviors to see whether any implement IWsdlImportExtension.
        context.Contract.Behaviors.Add(new WsdlDocumentationImporter(context.WsdlPortType.Documentation));
    }
    // Operation Documentation
    foreach (Operation operation in context.WsdlPortType.Operations)
    {
        if (operation.Documentation != null)
        {
            OperationDescription operationDescription = context.Contract.Operations.Find(operation.Name);
            if (operationDescription != null)
            {
                // System examines the operation behaviors to see whether any implement IWsdlImportExtension.
                operationDescription.Behaviors.Add(new WsdlDocumentationImporter(operation.Documentation));
            }
        }
    }
}

Ardından, kod oluşturulduğunda sistem uygun bağlam bilgilerini geçirerek ve GenerateOperation(OperationContractGenerationContext) yöntemlerini çağırırGenerateContract(ServiceContractGenerationContext). Örnek, özel WSDL ek açıklamalarını biçimlendirip CodeDom'a açıklama olarak ekler.

public void GenerateContract(ServiceContractGenerationContext context)
{
    Debug.WriteLine("In generate contract.");
    context.ContractType.Comments.AddRange(FormatComments(text));
}

public void GenerateOperation(OperationContractGenerationContext context)
{
    context.SyncMethod.Comments.AddRange(FormatComments(text));
    Debug.WriteLine("In generate operation.");
}

İstemci Uygulaması

İstemci uygulaması, özel WSDL içeri aktarıcısını uygulama yapılandırma dosyasında belirterek yükler.

<client>
  <endpoint address="http://localhost/servicemodelsamples/service.svc"
  binding="wsHttpBinding"
  contract="ICalculator" />
  <metadata>
    <wsdlImporters>
      <extension type="Microsoft.ServiceModel.Samples.WsdlDocumentationImporter, WsdlDocumentation"/>
    </wsdlImporters>
  </metadata>
</client>

Özel içeri aktarıcı belirtildikten sonra, WCF meta veri sistemi özel içeri aktarıcıyı bu amaç için oluşturulan herhangi bir WsdlImporter öğeye yükler. Bu örnek meta verileri indirmek için, WsdlImporter örneğin oluşturduğu ServiceContractGenerator özel içeri aktarıcıyı kullanarak meta verileri içeri aktarmak için doğru şekilde yapılandırılmış ve değiştirilen sözleşme bilgilerini Hem Visual Basic hem de C# istemci kodunda derleyip IntelliSense'i desteklemek veya XML belgelerinde derlenmek için Visual Studio'da kullanılabilecek şekilde kullanırMetadataExchangeClient.

/// From WSDL Documentation:
///
/// <summary>The ICalculator contract performs basic calculation
/// services.</summary>
///
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://Microsoft.ServiceModel.Samples", ConfigurationName="ICalculator")]
public interface ICalculator
{

    /// From WSDL Documentation:
    ///
    /// <summary>The Add operation adds two numbers and returns the
    /// result.</summary><returns>The result of adding the two arguments
    /// together.</returns><param name="n1">The first value to add.</param><param
    /// name="n2">The second value to add.</param>
    ///
    [System.ServiceModel.OperationContractAttribute(Action="http://Microsoft.ServiceModel.Samples/ICalculator/Add", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/AddResponse")]
    double Add(double n1, double n2);

    /// From WSDL Documentation:
    ///
    /// <summary>The Subtract operation subtracts the second argument from the
    /// first.</summary><returns>The result of the second argument subtracted from the
    /// first.</returns><param name="n1">The value from which the second is
    /// subtracted.</param><param name="n2">The value that is subtracted from the
    /// first.</param>
    ///
    [System.ServiceModel.OperationContractAttribute(Action="http://Microsoft.ServiceModel.Samples/ICalculator/Subtract", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/SubtractResponse")]
    double Subtract(double n1, double n2);

    /// From WSDL Documentation:
    ///
    /// <summary>The Multiply operation multiplies two values.</summary><returns>The
    /// result of multiplying the first and second arguments.</returns><param
    /// name="n1">The first value to multiply.</param><param name="n2">The second value
    /// to multiply.</param>
    ///
    [System.ServiceModel.OperationContractAttribute(Action="http://Microsoft.ServiceModel.Samples/ICalculator/Multiply", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/MultiplyResponse")]
    double Multiply(double n1, double n2);

    /// From WSDL Documentation:
    ///
    /// <summary>The Divide operation returns the value of the first argument divided
    /// by the second argument.</summary><returns>The result of dividing the first
    /// argument by the second.</returns><param name="n1">The numerator.</param><param
    /// name="n2">The denominator.</param>
    ///
    [System.ServiceModel.OperationContractAttribute(Action="http://Microsoft.ServiceModel.Samples/ICalculator/Divide", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/DivideResponse")]
    double Divide(double n1, double n2);
}

Örneği ayarlamak, derlemek ve çalıştırmak için

  1. Windows Communication Foundation Örnekleri için Tek Seferlik Kurulum Yordamı'nı gerçekleştirdiğinizden emin olun.

  2. Çözümün C# veya Visual Basic .NET sürümünü oluşturmak için Windows Communication Foundation Örnekleri Oluşturma başlığındaki yönergeleri izleyin.

  3. Örneği tek veya makineler arası bir yapılandırmada çalıştırmak için Windows Communication Foundation Örneklerini Çalıştırma başlığındaki yönergeleri izleyin.