Megosztás a következőn keresztül:


Egyéni WSDL-kiadvány

A WsdlDocumentation minta bemutatja, hogyan:

Feljegyzés

A minta telepítési eljárása és összeállítási utasításai a témakör végén találhatók.

Szolgáltatás

A mintában szereplő szolgáltatás két egyéni attribútummal van megjelölve. Az első, a WsdlDocumentationAttribute, elfogad egy sztringet a konstruktorban, és alkalmazható egy szerződési felület vagy művelet biztosítására egy olyan sztringgel, amely leírja a használatát. A második, WsdlParamOrReturnDocumentationAttributea műveletben szereplő értékek vagy paraméterek visszaadására alkalmazható. Az alábbi példa egy szolgáltatási szerződést mutat be, ICalculatoramely ezeket az attribútumokat használja.

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

A WsdlDocumentationAttribute implementálások IContractBehavior és IOperationBehavioraz attribútumpéldányok hozzá lesznek adva a megfelelőhöz ContractDescription vagy OperationDescription a szolgáltatás megnyitásakor. Az attribútum implementálja a következőt IWsdlExportExtensionis: . Amikor ExportContract(WsdlExporter, WsdlContractConversionContext) a rendszer meghívja, a WsdlExporter metaadatok exportálására használt és a WsdlContractConversionContext szolgáltatásleírási objektumokat tartalmazó objektumokat paraméterekként adja át, amelyek lehetővé teszik az exportált metaadatok módosítását.

Ebben a mintában attól függően, hogy az exportálási környezet objektuma rendelkezik-e ContractDescription vagy sem OperationDescription, a rendszer a szövegtulajdonság használatával kinyer egy megjegyzést az attribútumból, és hozzáadja a WSDL jegyzetelemhez az alábbi kódban látható módon.

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

Ha egy műveletet exportál, a minta tükröződés használatával kéri le a paraméterek értékeit WsdlParamOrReturnDocumentationAttribute , és visszaadja az értékeket, és hozzáadja őket a művelet WSDL-széljegyzetelemeihez az alábbiak szerint.

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

A minta ezután szabványos módon teszi közzé a metaadatokat az alábbi konfigurációs fájl használatával.

<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-ügyfél

Ez a minta nem használ Svcutil.exe. A szerződés a generatedClient.cs fájlban található, így miután a minta bemutatja az egyéni WSDL-importálást és -kódgenerálást, a szolgáltatás meghívható. Az alábbi egyéni WSDL-importáló ehhez a példához való használatához futtathatja a Svcutil.exe, és megadhatja a /svcutilConfig lehetőséget, megadva a mintában használt ügyfélkonfigurációs fájl elérési útját, amely a WsdlDocumentation.dll tárra hivatkozik. A betöltési WsdlDocumentationImporterSvuctil.exe azonban képesnek kell lennie az erőforrástár megkeresésére és betöltésére WsdlDocumentation.dll , ami azt jelenti, hogy regisztrálva van a globális szerelvény-gyorsítótárban, az elérési úton, vagy ugyanabban a könyvtárban van, mint Svcutil.exe. Egy ilyen egyszerű minta esetében a legegyszerűbb az, ha a Svcutil.exe és az ügyfélkonfigurációs fájlt ugyanabba a könyvtárba másolja, amelyből WsdlDocumentation.dll futtatja.

Az egyéni WSDL-importőr

Az egyéni IWsdlImportExtension objektum WsdlDocumentationImporter implementálja IContractBehavior és IOperationBehavior hozzáadja az importált ServiceEndpointokhoz, és IServiceContractGenerationExtensionIOperationContractGenerationExtension meghívja, hogy módosítsa a kódgenerálást a szerződés vagy a műveleti kód létrehozásakor.

Először a módszerben a ImportContract(WsdlImporter, WsdlContractConversionContext) minta meghatározza, hogy a WSDL-széljegyzet a szerződés vagy a művelet szintjén van-e, és viselkedésként adja hozzá magát a megfelelő hatókörhöz, és átadja az importált széljegyzetszöveget a konstruktornak.

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

Ezután a kód létrehozásakor a rendszer meghívja azokat GenerateContract(ServiceContractGenerationContext) és GenerateOperation(OperationContractGenerationContext) a metódusokat, és átadja a megfelelő környezeti információkat. A minta formázja az egyéni WSDL-széljegyzeteket, és megjegyzésként beszúrja őket a CodeDom-ba.

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.");
}

Az ügyfélalkalmazás

Az ügyfélalkalmazás betölti az egyéni WSDL-importálót az alkalmazáskonfigurációs fájlban való megadásával.

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

Miután megadta az egyéni importőrt, a WCF metaadat-rendszere betölti az egyéni importőrt az erre a célra létrehozott összes WsdlImporter példányba. Ez a minta a MetadataExchangeClient metaadatok letöltésére, a WsdlImporter metaadatok importálására a minta által létrehozott egyéni importőrrel való importálásra, valamint ServiceContractGenerator a módosított szerződésadatok Visual Basic és C# ügyfélkódba való fordítására szolgál, amelyek a Visual Studióban az Intellisense támogatásához vagy XML-dokumentációba való fordításhoz használhatók.

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

A minta beállítása, összeállítása és futtatása

  1. Győződjön meg arról, hogy elvégezte a Windows Communication Foundation-minták egyszeri beállítási eljárását.

  2. A megoldás C# vagy Visual Basic .NET kiadásának létrehozásához kövesse a Windows Communication Foundation-minták készítéséhez szükséges utasításokat.

  3. Ha a mintát egy vagy több gép közötti konfigurációban szeretné futtatni, kövesse a Windows Communication Foundation-minták futtatásával kapcsolatos utasításokat.