Delen via


Vergelijking van ASP.NET webservices met WCF op basis van ontwikkeling

Windows Communication Foundation (WCF) heeft een optie voor ASP.NET compatibiliteitsmodus waarmee WCF-toepassingen kunnen worden geprogrammeerd en geconfigureerd, zoals ASP.NET-webservices, en hun gedrag nabootsen. In de volgende secties worden ASP.NET webservices en WCF vergeleken op basis van wat vereist is voor het ontwikkelen van toepassingen met beide technologieën.

Gegevensweergave

De ontwikkeling van een webservice met ASP.NET begint meestal met het definiëren van complexe gegevenstypen die de service moet gebruiken. ASP.NET is afhankelijk van het XmlSerializer vertalen van gegevens die worden vertegenwoordigd door .NET Framework-typen naar XML voor verzending naar of van een service en het vertalen van gegevens die als XML zijn ontvangen naar .NET Framework-objecten. Voor het definiëren van de complexe gegevenstypen die een ASP.NET-service moet gebruiken, is de definitie van .NET Framework-klassen vereist die het XmlSerializer kan serialiseren naar en van XML. Dergelijke klassen kunnen handmatig worden geschreven of worden gegenereerd op basis van definities van de typen in XML-schema's met behulp van het opdrachtregelhulpprogramma XML-schema's/gegevenstypenondersteuning, xsd.exe.

Hier volgt een lijst met belangrijke problemen die u moet weten bij het definiëren van .NET Framework-klassen die kunnen XmlSerializer worden geserialiseerd naar en van XML:

  • Alleen de openbare velden en eigenschappen van .NET Framework-objecten worden omgezet in XML.

  • Exemplaren van verzamelingsklassen kunnen alleen in XML worden geserialiseerd als de klassen de IEnumerable of ICollection interface implementeren.

  • Klassen die de IDictionary interface implementeren, zoals Hashtable, kunnen niet in XML worden geserialiseerd.

  • De vele kenmerktypen in de System.Xml.Serialization naamruimte kunnen worden toegevoegd aan een .NET Framework-klasse en de bijbehorende leden om te bepalen hoe exemplaren van de klasse worden weergegeven in XML.

De ontwikkeling van WCF-toepassingen begint meestal ook met de definitie van complexe typen. WCF kan worden gemaakt om dezelfde .NET Framework-typen te gebruiken als ASP.NET-webservices.

De WCFDataContractAttribute en DataMemberAttribute kunnen worden toegevoegd aan .NET Framework-typen om aan te geven dat exemplaren van het type moeten worden geserialiseerd in XML en welke specifieke velden of eigenschappen van het type moeten worden geserialiseerd, zoals wordt weergegeven in de volgende voorbeeldcode.

//Example One:
[DataContract]
public class LineItem
{
    [DataMember]
    public string ItemNumber;
    [DataMember]
    public decimal Quantity;
    [DataMember]
    public decimal UnitPrice;
}

//Example Two:
public class LineItem
{
    [DataMember]
    private string itemNumber;
    [DataMember]
    private decimal quantity;
    [DataMember]
    private decimal unitPrice;

    public string ItemNumber
    {
      get
      {
          return this.itemNumber;
      }

      set
      {
          this.itemNumber = value;
      }
    }

    public decimal Quantity
    {
        get
        {
            return this.quantity;
        }

        set
        {
            this.quantity = value;
        }
    }

    public decimal UnitPrice
    {
      get
      {
          return this.unitPrice;
      }

      set
      {
          this.unitPrice = value;
      }
    }
}

//Example Three:
public class LineItem
{
     private string itemNumber;
     private decimal quantity;
     private decimal unitPrice;

     [DataMember]
     public string ItemNumber
     {
       get
       {
          return this.itemNumber;
       }

       set
       {
           this.itemNumber = value;
       }
     }

     [DataMember]
     public decimal Quantity
     {
          get
          {
              return this.quantity;
          }

          set
          {
             this.quantity = value;
          }
     }

     [DataMember]
     public decimal UnitPrice
     {
          get
          {
              return this.unitPrice;
          }

          set
          {
              this.unitPrice = value;
          }
     }
}

Hiermee DataContractAttribute wordt aangegeven dat nul of meer van de velden of eigenschappen van een type moeten worden geserialiseerd, terwijl wordt DataMemberAttribute aangegeven dat een bepaald veld of bepaalde eigenschap moet worden geserialiseerd. De DataContractAttribute kan worden toegepast op een klasse of structuur. De DataMemberAttribute waarden kunnen worden toegepast op een veld of eigenschap en de velden en eigenschappen waarop het kenmerk wordt toegepast, kunnen openbaar of privé zijn. Exemplaren van typen waarop de DataContractAttribute gegevenscontracten zijn toegepast, worden in WCF aangeduid als gegevenscontracten. Ze worden geserialiseerd in XML met behulp van DataContractSerializer.

Hier volgt een lijst met de belangrijke verschillen tussen het gebruik van en DataContractSerializer het gebruik van de XmlSerializer en de verschillende kenmerken van de System.Xml.Serialization naamruimte.

  • De XmlSerializer kenmerken van de System.Xml.Serialization naamruimte zijn zodanig ontworpen dat u .NET Framework-typen kunt toewijzen aan elk geldig type dat is gedefinieerd in XML-schema, zodat ze een zeer nauwkeurige controle bieden over de manier waarop een type wordt weergegeven in XML. De DataContractSerializer, DataContractAttribute en DataMemberAttribute bieden zeer weinig controle over hoe een type wordt weergegeven in XML. U kunt alleen de naamruimten en namen opgeven die worden gebruikt om het type en de bijbehorende velden of eigenschappen in de XML weer te geven, en de volgorde waarin de velden en eigenschappen worden weergegeven in de XML:

    [DataContract(
    Namespace="urn:Contoso:2006:January:29",
    Name="LineItem")]
    public class LineItem
    {
          [DataMember(Name="ItemNumber",IsRequired=true,Order=0)]
          public string itemNumber;
          [DataMember(Name="Quantity",IsRequired=false,Order = 1)]
          public decimal quantity;
          [DataMember(Name="Price",IsRequired=false,Order = 2)]
          public decimal unitPrice;
    }
    

    Alles over de structuur van de XML die wordt gebruikt om het .NET-type weer te geven, wordt bepaald door de DataContractSerializer.

  • Door niet veel controle te geven over de manier waarop een type moet worden weergegeven in XML, wordt het serialisatieproces zeer voorspelbaar voor de DataContractSerializer, en daardoor gemakkelijker te optimaliseren. Een praktisch voordeel van het ontwerp van de DataContractSerializer is betere prestaties, ongeveer tien procent betere prestaties.

  • De kenmerken voor gebruik met de XmlSerializer kenmerken geven niet aan welke velden of eigenschappen van het type worden geserialiseerd in XML, terwijl het DataMemberAttribute voor gebruik met de DataContractSerializer velden of eigenschappen expliciet wordt weergegeven welke velden of eigenschappen worden geserialiseerd. Daarom zijn gegevenscontracten expliciete contracten over de structuur van de gegevens die een toepassing moet verzenden en ontvangen.

  • Het XmlSerializer kan alleen de openbare leden van een .NET-object vertalen naar XML, de DataContractSerializer leden van objecten kunnen worden omgezet in XML, ongeacht de toegangsaanpassingen van die leden.

  • Als gevolg van het serialiseren van niet-openbare leden van typen in XML, hebben de DataContractSerializer minder beperkingen voor de verscheidenheid aan .NET-typen die in XML kunnen worden geserialiseerd. Het kan met name worden omgezet in XML-typen, zoals Hashtable die de IDictionary interface implementeren. Het DataContractSerializer is veel waarschijnlijker dat de exemplaren van een bestaand .NET-type in XML kunnen worden geserialiseerd zonder dat u de definitie van het type hoeft te wijzigen of een wrapper hiervoor hoeft te ontwikkelen.

  • Een ander gevolg van het DataContractSerializer feit dat de niet-openbare leden van een type kunnen worden geopend, is dat het volledige vertrouwen vereist, terwijl dat XmlSerializer niet het geval is. Met de machtiging Voor volledige vertrouwenscode krijgt u volledige toegang tot alle resources op een computer die toegankelijk is met behulp van de referenties waaronder de code wordt uitgevoerd. Deze optie moet zorgvuldig worden gebruikt als volledig vertrouwde code toegang heeft tot alle resources op uw computer.

  • De DataContractSerializer bevat enkele ondersteuning voor versiebeheer:

    • De DataMemberAttribute eigenschap heeft een IsRequired eigenschap die kan worden toegewezen aan onwaar voor leden die worden toegevoegd aan nieuwe versies van een gegevenscontract die niet aanwezig waren in eerdere versies, waardoor toepassingen met de nieuwere versie van het contract eerdere versies kunnen verwerken.

    • Door een gegevenscontract de IExtensibleDataObject interface te implementeren, kan de interface worden DataContractSerializer toegestaan om leden die zijn gedefinieerd in nieuwere versies van een gegevenscontract door te geven via toepassingen met eerdere versies van het contract.

Ondanks alle verschillen is de XML waarin een XmlSerializer type standaard wordt geserialiseerd, semantisch identiek aan de XML waarin het DataContractSerializer type serialiseert, mits de naamruimte voor de XML expliciet is gedefinieerd. De volgende klasse, die kenmerken heeft voor gebruik met beide serializers, wordt omgezet in semantisch identieke XML door de XmlSerializer en de DataContractAttribute:

[Serializable]
[XmlRoot(Namespace="urn:Contoso:2006:January:29")]
[DataContract(Namespace="urn:Contoso:2006:January:29")]
public class LineItem
{
     [DataMember]
     public string ItemNumber;
     [DataMember]
     public decimal Quantity;
     [DataMember]
     public decimal UnitPrice;
}

De Windows SDK (Software Development Kit) bevat een opdrachtregelprogramma met de naam ServiceModel Metadata Utility (Svcutil.exe). Net als het hulpprogramma xsd.exe dat wordt gebruikt met ASP.NET-webservices, kunnen Svcutil.exe definities van .NET-gegevenstypen genereren uit XML-schema. De typen zijn gegevenscontracten als de DataContractSerializer XML kan worden verzonden in de indeling die is gedefinieerd door het XML-schema; anders zijn ze bedoeld voor serialisatie met behulp van de XmlSerializer. Svcutil.exe kan ook een XML-schema genereren op basis van gegevenscontracten met behulp van de dataContractOnly switch.

Notitie

Hoewel ASP.NET webservices gebruikmaken van de XmlSerializercompatibiliteitsmodus , en WCF ASP.NET compatibiliteitsmodus, maken WCF-services het gedrag van ASP.NET webservices na, de ASP.NET compatibiliteitsoptie beperkt niet tot het gebruik van de XmlSerializer. U kunt de DataContractSerializer service nog steeds gebruiken die wordt uitgevoerd in de compatibiliteitsmodus ASP.NET.

Serviceontwikkeling

Voor het ontwikkelen van een service met behulp van ASP.NET is het gebruikelijk om het WebService kenmerk toe te voegen aan een klasse en de WebMethodAttribute methoden van die klasse die bewerkingen van de service moeten zijn:

[WebService]
public class Service : T:System.Web.Services.WebService
{
    [WebMethod]
    public string Echo(string input)
    {
       return input;
    }
}

ASP.NET 2.0 heeft de optie geïntroduceerd om het kenmerk WebService en WebMethodAttribute een interface toe te voegen in plaats van aan een klasse, en een klasse te schrijven om de interface te implementeren:

[WebService]
public interface IEcho
{
    [WebMethod]
    string Echo(string input);
}

public class Service : IEcho
{

   public string Echo(string input)
   {
        return input;
    }
}

Het gebruik van deze optie is de voorkeur, omdat de interface met het WebService kenmerk een contract vormt voor de bewerkingen die worden uitgevoerd door de service die kunnen worden hergebruikt met verschillende klassen die hetzelfde contract op verschillende manieren kunnen implementeren.

Een WCF-service wordt geleverd door een of meer WCF-eindpunten te definiëren. Een eindpunt wordt gedefinieerd door een adres, een binding en een servicecontract. Het adres definieert waar de service zich bevindt. De binding geeft aan hoe u met de service communiceert. Het servicecontract definieert de bewerkingen die de service kan uitvoeren.

Het servicecontract wordt meestal eerst gedefinieerd door een interface toe te voegen ServiceContractAttribute en OperationContractAttribute aan een interface:

[ServiceContract]
public interface IEcho
{
     [OperationContract]
     string Echo(string input);
}

De ServiceContractAttribute geeft aan dat de interface een WCF-servicecontract definieert en de OperationContractAttribute geeft aan welke, indien van toepassing, van de methoden van de interface bewerkingen van het servicecontract definiëren.

Zodra een servicecontract is gedefinieerd, wordt het geïmplementeerd in een klasse door de klasse de interface te laten implementeren waarmee het servicecontract is gedefinieerd:

public class Service : IEcho
{
    public string Echo(string input)
    {
       return input;
    }
}

Een klasse die een servicecontract implementeert, wordt een servicetype in WCF genoemd.

De volgende stap bestaat uit het koppelen van een adres en een binding aan een servicetype. Dit wordt meestal gedaan in een configuratiebestand door het bestand rechtstreeks te bewerken of door een configuratie-editor te gebruiken die is geleverd met WCF. Hier volgt een voorbeeld van een configuratiebestand.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
     <system.serviceModel>
      <services>
      <service name="Service ">
       <endpoint
        address="EchoService"
        binding="basicHttpBinding"
        contract="IEchoService "/>
      </service>
      </services>
     </system.serviceModel>
</configuration>

De binding geeft de set protocollen op voor communicatie met de toepassing. De volgende tabel bevat de door het systeem geleverde bindingen die algemene opties vertegenwoordigen.

Naam Doel
BasicHttpBinding Interoperabiliteit met webservices en clients die WS-BasicProfile 1.1 en Basic Security Profile 1.0 ondersteunen.
WSHttpBinding Interoperabiliteit met webservices en clients die ondersteuning bieden voor de WS-*-protocollen via HTTP.
WSDualHttpBinding Duplex HTTP-communicatie, waarmee de ontvanger van een eerste bericht niet rechtstreeks op de initiële afzender reageert, maar gedurende een bepaalde periode een willekeurig aantal reacties kan verzenden met behulp van HTTP in overeenstemming met WS-*-protocollen.
WSFederationBinding HTTP-communicatie, waarin toegang tot de resources van een service kan worden beheerd op basis van referenties die zijn uitgegeven door een expliciet geïdentificeerde referentieprovider.
NetTcpBinding Veilige, betrouwbare, krachtige communicatie tussen WCF-software-entiteiten in een netwerk.
NetNamedPipeBinding Veilige, betrouwbare, krachtige communicatie tussen WCF-software-entiteiten op dezelfde computer.
NetMsmqBinding Communicatie tussen WCF-software-entiteiten met behulp van MSMQ.
MsmqIntegrationBinding Communicatie tussen een WCF-software-entiteit en een andere software-entiteit met behulp van MSMQ.
NetPeerTcpBinding Communicatie tussen WCF-software-entiteiten met behulp van Windows Peer-to-Peer Networking.

De door het systeem geleverde binding bevat BasicHttpBindingde set protocollen die worden ondersteund door ASP.NET-webservices.

Aangepaste bindingen voor WCF-toepassingen kunnen eenvoudig worden gedefinieerd als verzamelingen van de bindingselementklassen die WCF gebruikt om afzonderlijke protocollen te implementeren. Nieuwe bindingselementen kunnen worden geschreven om extra protocollen weer te geven.

Het interne gedrag van servicetypen kan worden aangepast met behulp van de eigenschappen van een reeks klassen die gedrag worden genoemd. Hier wordt de ServiceBehaviorAttribute klasse gebruikt om op te geven dat het servicetype multithreaded moet zijn.

[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Multiple)]
public class DerivativesCalculatorServiceType: IDerivativesCalculator

Sommige gedragingen, zoals ServiceBehaviorAttribute, zijn kenmerken. Andere, de eigenschappen die beheerders willen instellen, kunnen worden gewijzigd in de configuratie van een toepassing.

Bij programmeerservicetypen wordt frequent gebruik gemaakt van de OperationContext klasse. De statische Current eigenschap biedt toegang tot informatie over de context waarin een bewerking wordt uitgevoerd. OperationContextis vergelijkbaar met zowel de als ContextUtil de HttpContext klassen.

Hosting

ASP.NET webservices worden gecompileerd in een klassebibliotheekassembly. Een bestand met de naam van het servicebestand wordt geleverd met de extensie .asmx en bevat een @ WebService instructie die de klasse identificeert die de code voor de service en de assembly waarin deze zich bevindt.

<%@ WebService Language="C#" Class="Service,ServiceAssembly" %>

Het servicebestand wordt gekopieerd naar een ASP.NET toepassingshoofdmap in Internet Information Services (IIS) en de assembly wordt gekopieerd naar de submap \bin van de hoofdmap van die toepassing. De toepassing is vervolgens toegankelijk met behulp van de UNIFORM Resource Locator (URL) van het servicebestand in de hoofdmap van de toepassing.

WCF-services kunnen gemakkelijk worden gehost binnen IIS 5.1 of 6.0, de Windows Process Activation Service (WAS) die wordt geleverd als onderdeel van IIS 7.0 en binnen een .NET-toepassing. Als u een service in IIS 5.1 of 6.0 wilt hosten, moet de service HTTP gebruiken als communicatietransportprotocol.

Als u een service wilt hosten binnen IIS 5.1, 6.0 of binnen WAS, gebruikt u de volgende stappen:

  1. Compileer het servicetype in een klassebibliotheekassembly.

  2. Maak een servicebestand met de extensie .svc met een @ ServiceHost instructie om het servicetype te identificeren:

    <%@ServiceHost language="c#" Service="MyService" %>

  3. Kopieer het servicebestand naar een virtuele map en de assembly naar de submap \bin van die virtuele map.

  4. Kopieer het configuratiebestand naar de virtuele map en geef het web.config een naam.

De toepassing is vervolgens toegankelijk via de URL van het servicebestand in de hoofdmap van de toepassing.

Als u een WCF-service in een .NET-toepassing wilt hosten, compileert u het servicetype in een klassebibliotheekassembly waarnaar wordt verwezen door de toepassing en programmeert u de toepassing om de service te hosten met behulp van de ServiceHost klasse. Hier volgt een voorbeeld van de basisprogrammering die is vereist:

string httpBaseAddress = "http://www.contoso.com:8000/";
string tcpBaseAddress = "net.tcp://www.contoso.com:8080/";

Uri httpBaseAddressUri = new Uri(httpBaseAddress);
Uri tcpBaseAddressUri = new Uri(tcpBaseAddress);

Uri[] baseAddresses = new Uri[] {
 httpBaseAddressUri,
 tcpBaseAddressUri};

using(ServiceHost host = new ServiceHost(
typeof(Service), //"Service" is the name of the service type baseAddresses))
{
     host.Open();

     […] //Wait to receive messages
     host.Close();
}

In dit voorbeeld ziet u hoe adressen voor een of meer transportprotocollen worden opgegeven in de constructie van een ServiceHost. Deze adressen worden basisadressen genoemd.

Het adres dat is opgegeven voor een eindpunt van een WCF-service is een adres ten opzichte van een basisadres van de host van het eindpunt. De host kan één basisadres hebben voor elk communicatietransportprotocol. In de voorbeeldconfiguratie in het voorgaande configuratiebestand gebruikt de BasicHttpBinding geselecteerde voor het eindpunt HTTP als transportprotocol, dus het adres van het eindpunt, EchoServiceis relatief ten opzichte van het HTTP-basisadres van de host. In het geval van de host in het vorige voorbeeld is het HTTP-basisadres http://www.contoso.com:8000/. Voor een service die wordt gehost in IIS of WAS, is het basisadres de URL van het servicebestand van de service.

Alleen services die worden gehost in IIS of WAS en die uitsluitend zijn geconfigureerd met HTTP als transportprotocol, kunnen worden gemaakt voor het gebruik van WCF-ASP.NET compatibiliteitsmodusoptie. Voor het inschakelen van deze optie zijn de volgende stappen vereist.

  1. De programmeur moet het AspNetCompatibilityRequirementsAttribute kenmerk toevoegen aan het servicetype en opgeven dat ASP.NET compatibiliteitsmodus is toegestaan of vereist.

    [System.ServiceModel.Activation.AspNetCompatibilityRequirements(
          RequirementsMode=AspNetCompatibilityRequirementsMode.Require)]
    public class DerivativesCalculatorServiceType: IDerivativesCalculator
    
  2. De beheerder moet de toepassing configureren voor gebruik van de compatibiliteitsmodus ASP.NET.

    <configuration>
         <system.serviceModel>
          <services>
          […]
          </services>
          <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
        </system.serviceModel>
    </configuration>
    

    WCF-toepassingen kunnen ook worden geconfigureerd voor het gebruik van .asmx als extensie voor hun servicebestanden in plaats van .svc.

    <system.web>
         <compilation>
          <compilation debug="true">
          <buildProviders>
           <remove extension=".asmx"/>
           <add extension=".asmx"
            type="System.ServiceModel.ServiceBuildProvider,
            System.ServiceModel,
            Version=3.0.0.0,
            Culture=neutral,
            PublicKeyToken=b77a5c561934e089" />
          </buildProviders>
          </compilation>
         </compilation>
    </system.web>
    

    Met deze optie kunt u voorkomen dat u clients moet wijzigen die zijn geconfigureerd voor het gebruik van de URL's van .asmx-servicebestanden bij het wijzigen van een service voor het gebruik van WCF.

Clientontwikkeling

Clients voor ASP.NET-webservices worden gegenereerd met behulp van het opdrachtregelprogramma WSDL.exe, dat de URL van het ASMX-bestand als invoer levert. Het bijbehorende hulpprogramma dat door WCF wordt geleverd, is het hulpprogramma voor metagegevens van ServiceModel (Svcutil.exe). Er wordt een codemodule gegenereerd met de definitie van het servicecontract en de definitie van een WCF-clientklasse. Er wordt ook een configuratiebestand gegenereerd met het adres en de binding van de service.

Bij het programmeren van een client van een externe service is het over het algemeen raadzaam om te programmeren volgens een asynchroon patroon. De code die door het hulpprogramma WSDL.exe wordt gegenereerd, biedt altijd standaard zowel een synchroon als een asynchroon patroon. De code die wordt gegenereerd door het hulpprogramma voor metagegevens van ServiceModel (Svcutil.exe) kan beide patronen bevatten. Het biedt standaard het synchrone patroon. Als het hulpprogramma wordt uitgevoerd met de /async switch, biedt de gegenereerde code het asynchrone patroon.

Er is geen garantie dat namen in de WCF-clientklassen die zijn gegenereerd door het WSDL.exe-hulpprogramma van ASP.NET, standaard overeenkomen met de namen in WCF-clientklassen die zijn gegenereerd door het hulpprogramma Svcutil.exe. In het bijzonder zijn de namen van de eigenschappen van klassen die moeten worden geserialiseerd met behulp van de XmlSerializer standaardinstelling, gezien de achtervoegseleigenschap in de code die is gegenereerd door het hulpprogramma Svcutil.exe, wat niet het geval is met het hulpprogramma WSDL.exe.

Berichtweergave

De headers van de SOAP-berichten die door ASP.NET webservices worden verzonden en ontvangen, kunnen worden aangepast. Een klasse wordt afgeleid van SoapHeader het definiëren van de structuur van de header en vervolgens wordt de SoapHeaderAttribute klasse gebruikt om de aanwezigheid van de header aan te geven.

public class SomeProtocol : SoapHeader
{
     public long CurrentValue;
     public long Total;
}

[WebService]
public interface IEcho
{
     SomeProtocol ProtocolHeader
     {
      get;
     set;
     }

     [WebMethod]
     [SoapHeader("ProtocolHeader")]
     string PlaceOrders(PurchaseOrderType order);
}

public class Service: WebService, IEcho
{
     private SomeProtocol protocolHeader;

     public SomeProtocol ProtocolHeader
     {
         get
         {
              return this.protocolHeader;
         }

         set
         {
              this.protocolHeader = value;
         }
     }

     string PlaceOrders(PurchaseOrderType order)
     {
         long currentValue = this.protocolHeader.CurrentValue;
     }
}

De WCF biedt de kenmerken, MessageContractAttribute, MessageHeaderAttributeen MessageBodyMemberAttribute om de structuur van de SOAP-berichten te beschrijven die door een service worden verzonden en ontvangen.

[DataContract]
public class SomeProtocol
{
     [DataMember]
     public long CurrentValue;
     [DataMember]
     public long Total;
}

[DataContract]
public class Item
{
     [DataMember]
     public string ItemNumber;
     [DataMember]
     public decimal Quantity;
     [DataMember]
     public decimal UnitPrice;
}

[MessageContract]
public class ItemMessage
{
     [MessageHeader]
     public SomeProtocol ProtocolHeader;
     [MessageBody]
     public Item Content;
}

[ServiceContract]
public interface IItemService
{
     [OperationContract]
     public void DeliverItem(ItemMessage itemMessage);
}

Deze syntaxis geeft een expliciete weergave van de structuur van de berichten, terwijl de structuur van berichten wordt geïmpliceerd door de code van een ASP.NET-webservice. In de syntaxis van de ASP.NET worden berichtkoppen ook weergegeven als eigenschappen van de service, zoals de ProtocolHeader eigenschap in het vorige voorbeeld, terwijl ze in de WCF-syntaxis nauwkeuriger worden weergegeven als eigenschappen van berichten. Met WCF kunnen berichtkoppen ook worden toegevoegd aan de configuratie van eindpunten.

<service name="Service ">
     <endpoint
      address="EchoService"
      binding="basicHttpBinding"
      contract="IEchoService ">
      <headers>
      <dsig:X509Certificate
       xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
       ...
      </dsig:X509Certificate>
      </headers>
     </endpoint>
</service>

Met deze optie kunt u verwijzingen naar infrastructuurprotocolheaders in de code voor een client of service voorkomen: de headers worden toegevoegd aan berichten vanwege de manier waarop het eindpunt is geconfigureerd.

Beschrijving van de service

Het uitgeven van een HTTP GET-aanvraag voor het ASMX-bestand van een ASP.NET-webservice met de query die WSDL uitvoert, zorgt ervoor dat ASP.NET WSDL genereert om de service te beschrijven. WSDL wordt geretourneerd als reactie op de aanvraag.

ASP.NET 2.0 heeft het mogelijk gemaakt om te valideren dat een service voldoet aan het basisprofiel 1.1 van de WS-I (Web Services-Interoperability Organization) en een claim invoegt dat de service voldoet aan de WSDL. Dat gebeurt met behulp van de ConformsTo en EmitConformanceClaims parameters van het WebServiceBindingAttribute kenmerk.

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(
     ConformsTo = WsiProfiles.BasicProfile1_1,
     EmitConformanceClaims=true)]
public interface IEcho

De WSDL die ASP.NET genereert voor een service, kan worden aangepast. Aanpassingen worden gemaakt door een afgeleide klasse te maken van het toevoegen van ServiceDescriptionFormatExtension items aan de WSDL.

Het uitgeven van een HTTP GET-aanvraag met de query WSDL voor het .svc-bestand van een WCF-service met een HTTP-eindpunt dat wordt gehost in IIS 51, 6.0 of WAS zorgt ervoor dat WCF reageert met WSDL om de service te beschrijven. Het uitgeven van een HTTP GET-aanvraag met de query WSDL naar het HTTP-basisadres van een service die wordt gehost in een .NET-toepassing heeft hetzelfde effect als httpGetEnabled is ingesteld op waar.

WCF reageert echter ook op WS-MetadataExchange-aanvragen met WSDL die worden gegenereerd om een service te beschrijven. ASP.NET webservices hebben geen ingebouwde ondersteuning voor WS-MetadataExchange-aanvragen.

De WSDL die WCF genereert, kan uitgebreid worden aangepast. De ServiceMetadataBehavior klasse biedt enkele faciliteiten voor het aanpassen van de WSDL. De WCF kan ook worden geconfigureerd om geen WSDL te genereren, maar om een statisch WSDL-bestand op een bepaalde URL te gebruiken.

<behaviors>
     <behavior name="DescriptionBehavior">
     <metadataPublishing
      enableMetadataExchange="true"
      enableGetWsdl="true"
      enableHelpPage="true"
      metadataLocation=
      "http://localhost/DerivativesCalculatorService/Service.WSDL"/>
     </behavior>
</behaviors>

Afhandeling van uitzonderingen

In ASP.NET webservices worden niet-verwerkte uitzonderingen geretourneerd naar clients als SOAP-fouten. U kunt ook expliciet instanties van de SoapException klasse gooien en meer controle hebben over de inhoud van de SOAP-fout die naar de client wordt verzonden.

In WCF-services worden niet-verwerkte uitzonderingen niet naar clients geretourneerd als SOAP-fouten om te voorkomen dat gevoelige informatie per ongeluk wordt weergegeven via de uitzonderingen. Er wordt een configuratie-instelling geboden om niet-verwerkte uitzonderingen te laten retourneren aan clients voor foutopsporing.

Als u SOAP-fouten wilt retourneren aan clients, kunt u exemplaren van het algemene type gooien, FaultException<TDetail>met behulp van het gegevenscontracttype als het algemene type. U kunt ook kenmerken toevoegen FaultContractAttribute aan bewerkingen om de fouten op te geven die een bewerking kan opleveren.

[DataContract]
public class MathFault
{
     [DataMember]
     public string operation;
     [DataMember]
     public string problemType;
}

[ServiceContract]
public interface ICalculator
{
     [OperationContract]
     [FaultContract(typeof(MathFault))]
     int Divide(int n1, int n2);
}

Dit resulteert in de mogelijke fouten die worden geadverteerd in de WSDL voor de service, zodat clientprogrammeurs kunnen anticiperen op welke fouten uit een bewerking kunnen voortvloeien en de juiste catch-instructies schrijven.

try
{
     result = client.Divide(value1, value2);
}
catch (FaultException<MathFault> e)
{
 Console.WriteLine("FaultException<MathFault>: Math fault while doing "
  + e.Detail.operation
  + ". Problem: "
  + e.Detail.problemType);
}

Statusbeheer

De klasse die wordt gebruikt om een ASP.NET-webservice te implementeren, kan worden afgeleid van WebService.

public class Service : WebService, IEcho
{

 public string Echo(string input)
 {
  return input;
 }
}

In dat geval kan de klasse worden geprogrammeerd om de contexteigenschap van de WebService basisklasse te gebruiken voor toegang tot een HttpContext object. Het HttpContext object kan worden gebruikt om statusgegevens van toepassingen bij te werken en op te halen met behulp van de toepassingseigenschap en kan worden gebruikt om sessiestatusgegevens bij te werken en op te halen met behulp van de eigenschap Sessie.

ASP.NET biedt aanzienlijke controle over waar de sessiestatusgegevens worden geopend met behulp van de eigenschap Sessie van de daadwerkelijk HttpContext opgeslagen. Het kan worden opgeslagen in cookies, in een database, in het geheugen van de huidige server of in het geheugen van een aangewezen server. De keuze wordt gemaakt in het configuratiebestand van de service.

WcF biedt uitbreidbare objecten voor statusbeheer. Uitbreidbare objecten zijn objecten die worden geïmplementeerd IExtensibleObject<T>. De belangrijkste uitbreidbare objecten zijn ServiceHostBase en InstanceContext. ServiceHostBase hiermee kunt u de status behouden die alle exemplaren van alle servicetypen op dezelfde host kunnen openen, terwijl InstanceContext u de status kunt behouden die toegankelijk is voor elke code die wordt uitgevoerd binnen hetzelfde exemplaar van een servicetype.

Hier, het servicetype, TradingSystembevat een ServiceBehaviorAttribute die aanroept dat alle aanroepen van hetzelfde WCF-clientexemplaren worden gerouteerd naar hetzelfde exemplaar van het servicetype.

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class TradingSystem: ITradingService

De klasse, DealDatadefinieert de status die kan worden geopend door elke code die wordt uitgevoerd in hetzelfde exemplaar van een servicetype.

internal class DealData: IExtension<InstanceContext>
{
 public string DealIdentifier = null;
 public Trade[] Trades = null;
}

In de code van het servicetype dat een van de bewerkingen van het servicecontract implementeert, wordt een DealData statusobject toegevoegd aan de status van het huidige exemplaar van het servicetype.

string ITradingService.BeginDeal()
{
 string dealIdentifier = Guid.NewGuid().ToString();
 DealData state = new DealData(dealIdentifier);
 OperationContext.Current.InstanceContext.Extensions.Add(state);
 return dealIdentifier;
}

Dat statusobject kan vervolgens worden opgehaald en gewijzigd door de code waarmee een andere bewerking van het servicecontract wordt geïmplementeerd.

void ITradingService.AddTrade(Trade trade)
{
 DealData dealData =  OperationContext.Current.InstanceContext.Extensions.Find<DealData>();
 dealData.AddTrade(trade);
}

Terwijl ASP.NET controle geeft over waar statusinformatie in de HttpContext klasse daadwerkelijk wordt opgeslagen, biedt WCF, ten minste in de oorspronkelijke versie, geen controle over waar uitbreidbare objecten worden opgeslagen. Dit is de beste reden voor het selecteren van de ASP.NET compatibiliteitsmodus voor een WCF-service. Als configureerbaar statusbeheer noodzakelijk is, kunt u ervoor kiezen om de compatibiliteitsmodus ASP.NET de faciliteiten van de HttpContext klasse precies te gebruiken zoals ze worden gebruikt in ASP.NET, en om te configureren waar statusgegevens die worden beheerd met behulp van de HttpContext klasse worden opgeslagen.

Beveiliging

De opties voor het beveiligen van ASP.NET-webservices zijn die voor het beveiligen van een IIS-toepassing. Omdat WCF-toepassingen niet alleen binnen IIS maar ook binnen een uitvoerbaar .NET-bestand kunnen worden gehost, moeten de opties voor het beveiligen van WCF-toepassingen onafhankelijk van de faciliteiten van IIS worden gemaakt. De faciliteiten voor ASP.NET webservices zijn echter ook beschikbaar voor WCF-services die worden uitgevoerd in ASP.NET compatibiliteitsmodus.

Beveiliging: verificatie

IIS biedt faciliteiten voor het beheren van de toegang tot toepassingen waarmee u anonieme toegang of verschillende verificatiemodi kunt selecteren: Windows-verificatie, Digest-verificatie, Basisverificatie en .NET Passport-verificatie. De optie Windows-verificatie kan worden gebruikt om de toegang tot ASP.NET webservices te beheren. Wanneer WCF-toepassingen echter worden gehost binnen IIS, moet IIS worden geconfigureerd om anonieme toegang tot de toepassing toe te staan, zodat verificatie kan worden beheerd door WCF zelf, wat ondersteuning biedt voor Windows-verificatie onder verschillende andere opties. De andere opties die zijn ingebouwd, zijn gebruikersnaamtokens, X.509-certificaten, SAML-tokens en CardSpace-kaart, maar aangepaste verificatiemechanismen kunnen ook worden gedefinieerd.

Beveiliging: imitatie

ASP.NET biedt een identiteitselement waarmee een ASP.NET-webservice kan worden gemaakt om een bepaalde gebruiker te imiteren of de referenties van de gebruiker die bij de huidige aanvraag zijn opgegeven. Dit element kan worden gebruikt voor het configureren van imitatie in WCF-toepassingen die worden uitgevoerd in ASP.NET compatibiliteitsmodus.

Het WCF-configuratiesysteem biedt een eigen identiteitselement voor het aanwijzen van een bepaalde gebruiker om zich te imiteren. WcF-clients en -services kunnen ook onafhankelijk worden geconfigureerd voor imitatie. Clients kunnen worden geconfigureerd om de huidige gebruiker te imiteren wanneer ze aanvragen verzenden.

<behaviors>
     <behavior name="DerivativesCalculatorClientBehavior">
      <clientCredentials>
      <windows allowedImpersonationLevel="Impersonation"/>
      </clientCredentials>
     </behavior>
</behaviors>

Servicebewerkingen kunnen worden geconfigureerd om te imiteren welke gebruikersreferenties bij de huidige aanvraag zijn opgegeven.

[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public void Receive(Message input)

Beveiliging: Autorisatie met behulp van toegangsbeheerlijsten

Toegangsbeheerlijsten (ACL's) kunnen worden gebruikt om de toegang tot .asmx-bestanden te beperken. ACL's op WCF.svc-bestanden worden echter genegeerd, behalve in ASP.NET compatibiliteitsmodus.

Beveiliging: Autorisatie op basis van rollen

De optie IIS Windows-verificatie kan worden gebruikt in combinatie met het autorisatie-element dat wordt geleverd door de ASP.NET-configuratietaal om autorisatie op basis van rollen te vergemakkelijken voor ASP.NET-webservices op basis van de Windows-groepen waaraan gebruikers zijn toegewezen. ASP.NET 2.0 heeft een meer algemeen autorisatiemechanisme op basis van rollen geïntroduceerd: rolproviders.

Rolproviders zijn klassen die allemaal een basisinterface implementeren voor het invragen van de rollen waaraan een gebruiker is toegewezen, maar elke rolprovider weet hoe die informatie uit een andere bron kan worden opgehaald. ASP.NET 2.0 biedt een rolprovider waarmee roltoewijzingen kunnen worden opgehaald uit een Microsoft SQL Server-database en een andere provider die roltoewijzingen kan ophalen uit Windows Server 2003 Authorization Manager.

Het mechanisme van de rolprovider kan onafhankelijk van ASP.NET worden gebruikt in elke .NET-toepassing, met inbegrip van een WCF-toepassing. In de volgende voorbeeldconfiguratie voor een WCF-toepassing ziet u hoe het gebruik van een ASP.NET rolprovider een optie is die is geselecteerd met behulp van de ServiceAuthorizationBehavior.

<system.serviceModel>
     <services>
         <service name="Service.ResourceAccessServiceType"
             behaviorConfiguration="ServiceBehavior">
             <endpoint
              address="ResourceAccessService"
              binding="wsHttpBinding"
              contract="Service.IResourceAccessContract"/>
         </service>
     </services>
     <behaviors>
       <behavior name="ServiceBehavior">
       <serviceAuthorization principalPermissionMode="UseAspNetRoles"/>
      </behavior>
     </behaviors>
</system.serviceModel>

Beveiliging: Autorisatie op basis van claims

Een van de belangrijkste innovaties van WCF is de grondige ondersteuning voor het autoriseren van toegang tot beveiligde resources op basis van claims. Claims bestaan bijvoorbeeld uit een type, een recht en een waarde, een rijbewijs. Het maakt een reeks claims over de bearer, waarvan een is de geboortedatum van de bearer. Het type van die claim is de geboortedatum, terwijl de waarde van de claim de geboortedatum van de bestuurder is. Het recht dat een claim aan de bearer verleent, geeft aan wat de bearer kan doen met de waarde van de claim. In het geval van de vordering van de geboortedatum van de bestuurder, is het recht bezit: de bestuurder bezit die geboortedatum, maar kan deze bijvoorbeeld niet wijzigen. Autorisatie op basis van claims omvat op rollen gebaseerde autorisatie, omdat rollen een type claim zijn.

Autorisatie op basis van claims wordt bereikt door een set claims te vergelijken met de toegangsvereisten van de bewerking en, afhankelijk van het resultaat van die vergelijking, het verlenen of weigeren van toegang tot de bewerking. In WCF kunt u een klasse opgeven die moet worden gebruikt om autorisatie op basis van claims uit te voeren, opnieuw door een waarde toe te wijzen aan de ServiceAuthorizationManager eigenschap van ServiceAuthorizationBehavior.

<behaviors>
     <behavior name='ServiceBehavior'>
     <serviceAuthorization
     serviceAuthorizationManagerType=
                   'Service.AccessChecker, Service' />
     </behavior>
</behaviors>

Klassen die worden gebruikt voor het uitvoeren van autorisatie op basis van claims, moeten zijn afgeleid van ServiceAuthorizationManager, die slechts één methode heeft om te overschrijven, AccessCheck(). WCF roept deze methode aan wanneer een bewerking van de service wordt aangeroepen en biedt een OperationContext object, dat de claims voor de gebruiker in ServiceSecurityContext.AuthorizationContext de eigenschap bevat. WCF doet het werk van het samenstellen van claims over de gebruiker van elk beveiligingstoken dat de gebruiker heeft opgegeven voor verificatie, waardoor de taak blijft om te evalueren of deze claims voldoende zijn voor de betreffende bewerking.

Dat WCF automatisch claims verzamelt van elk type beveiligingstoken is een zeer belangrijke innovatie, omdat de code voor autorisatie op basis van de claims volledig onafhankelijk van het verificatiemechanisme wordt. Autorisatie met ACL's of rollen in ASP.NET is daarentegen nauw gekoppeld aan Windows-verificatie.

Beveiliging: vertrouwelijkheid

De vertrouwelijkheid van berichten die worden uitgewisseld met ASP.NET-webservices kan op transportniveau worden gegarandeerd door de toepassing in IIS te configureren voor gebruik van het Secure Hypertext Transfer Protocol (HTTPS). Hetzelfde kan worden gedaan voor WCF-toepassingen die worden gehost in IIS. WCF-toepassingen die buiten IIS worden gehost, kunnen echter ook worden geconfigureerd voor het gebruik van een beveiligd transportprotocol. Belangrijker is dat WCF-toepassingen ook kunnen worden geconfigureerd om de berichten te beveiligen voordat ze worden vervoerd, met behulp van het WS-Security-protocol. Door alleen de hoofdtekst van een bericht te beveiligen met WS-Security, kan het vertrouwelijk worden verzonden tussen tussenpersonen voordat deze de uiteindelijke bestemming bereikt.

Globalisatie

Met de ASP.NET configuratietaal kunt u de cultuur voor afzonderlijke services opgeven. De WCF biedt geen ondersteuning voor deze configuratie-instelling, behalve in ASP.NET compatibiliteitsmodus. Als u een WCF-service wilt lokaliseren die geen gebruik maakt van ASP.NET compatibiliteitsmodus, compileert u het servicetype in cultuurspecifieke assembly's en beschikt u over afzonderlijke cultuurspecifieke eindpunten voor elke cultuurspecifieke assembly.

Zie ook