Jämföra ASP.NET webbtjänster med WCF baserat på utveckling
Windows Communication Foundation (WCF) har ett ASP.NET kompatibilitetsläge för att göra det möjligt för WCF-program att programmeras och konfigureras som ASP.NET webbtjänster och efterlikna deras beteende. I följande avsnitt jämförs ASP.NET webbtjänster och WCF baserat på vad som krävs för att utveckla program med hjälp av båda teknikerna.
Datarepresentation
Utvecklingen av en webbtjänst med ASP.NET börjar vanligtvis med att definiera alla komplexa datatyper som tjänsten ska använda. ASP.NET förlitar sig på XmlSerializer att översätta data som representeras av .NET Framework-typer till XML för överföring till eller från en tjänst och för att översätta data som tagits emot som XML till .NET Framework-objekt. För att definiera de komplexa datatyper som en ASP.NET tjänst ska använda krävs definitionen av .NET Framework-klasser som XmlSerializer kan serialiseras till och från XML. Sådana klasser kan skrivas manuellt eller genereras från definitioner av typerna i XML-schema med hjälp av kommandoradsverktyget för XML-scheman/datatyper, xsd.exe.
Följande är en lista över viktiga problem att känna till när du definierar .NET Framework-klasser som XmlSerializer kan serialisera till och från XML:
Endast offentliga fält och egenskaper för .NET Framework-objekt översätts till XML.
Instanser av samlingsklasser kan endast serialiseras till XML om klasserna implementerar antingen IEnumerable gränssnittet eller ICollection .
Klasser som implementerar IDictionary gränssnittet, till exempel Hashtable, kan inte serialiseras till XML.
De många attributtyperna System.Xml.Serialization i namnområdet kan läggas till i en .NET Framework-klass och dess medlemmar för att styra hur instanser av klassen representeras i XML.
WCF-programutveckling börjar vanligtvis också med definitionen av komplexa typer. WCF kan göras för att använda samma .NET Framework-typer som ASP.NET webbtjänster.
WCFDataContractAttribute och DataMemberAttribute kan läggas till i .NET Framework-typer för att indikera att instanser av typen ska serialiseras till XML och vilka specifika fält eller egenskaper av typen som ska serialiseras, enligt följande exempelkod.
//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;
}
}
}
Betyder DataContractAttribute att noll eller fler av en typs fält eller egenskaper ska serialiseras, medan DataMemberAttribute indikerar att ett visst fält eller en viss egenskap ska serialiseras. DataContractAttribute Kan tillämpas på en klass eller struktur. DataMemberAttribute Kan tillämpas på ett fält eller en egenskap, och fälten och egenskaperna som attributet tillämpas på kan vara antingen offentliga eller privata. Instanser av typer som har DataContractAttribute tillämpats på dem kallas för datakontrakt i WCF. De serialiseras till XML med hjälp av DataContractSerializer.
Följande är en lista över de viktiga skillnaderna mellan att använda DataContractSerializer och använda XmlSerializer och de olika attributen i System.Xml.Serialization namnområdet.
Attributen XmlSerializerSystem.Xml.Serialization och för namnområdet är utformade så att du kan mappa .NET Framework-typer till valfri giltig typ som definierats i XML-schema, så att de ger mycket exakt kontroll över hur en typ representeras i XML. och DataContractSerializerDataContractAttributeDataMemberAttribute ger mycket liten kontroll över hur en typ representeras i XML. Du kan bara ange de namnområden och namn som används för att representera typen och dess fält eller egenskaper i XML:en och sekvensen där fälten och egenskaperna visas i XML:en:
[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; }
Allt annat om strukturen för DEN XML som används för att representera .NET-typen bestäms av DataContractSerializer.
Genom att inte tillåta mycket kontroll över hur en typ ska representeras i XML blir serialiseringsprocessen mycket förutsägbar för DataContractSerializer, och därmed enklare att optimera. En praktisk fördel med designen DataContractSerializer av är bättre prestanda, cirka tio procent bättre prestanda.
Attributen för användning med XmlSerializer anger inte vilka fält eller egenskaper av typen som serialiseras till XML, medan DataMemberAttribute för användning med visar uttryckligen DataContractSerializer vilka fält eller egenskaper som serialiseras. Därför är datakontrakt explicita kontrakt om strukturen för de data som ett program ska skicka och ta emot.
XmlSerializer Kan bara översätta de offentliga medlemmarna i ett .NET-objekt till XML, DataContractSerializer kan översätta objektmedlemmar till XML oavsett åtkomstmodifierare för dessa medlemmar.
Som en följd av att kunna serialisera icke-offentliga medlemmar av typer till XML har DataContractSerializer färre begränsningar för de olika .NET-typer som kan serialiseras till XML. I synnerhet kan det översättas till XML-typer som Hashtable implementerar IDictionary gränssnittet. Det DataContractSerializer är mycket mer sannolikt att kunna serialisera instanserna av en befintlig .NET-typ till XML utan att behöva ändra definitionen av typen eller utveckla en omslutning för den.
En annan konsekvens av DataContractSerializer att kunna få åtkomst till icke-offentliga medlemmar av en typ är att det kräver fullständigt förtroende, medan XmlSerializer det inte gör det. Åtkomstbehörigheten Fullständig förtroendekod ger fullständig åtkomst till alla resurser på en dator som kan nås med hjälp av de autentiseringsuppgifter som koden körs under. Det här alternativet bör användas med försiktighet eftersom fullständigt betrodd kod har åtkomst till alla resurser på datorn.
Innehåller DataContractSerializer visst stöd för versionshantering:
DataMemberAttribute Har en IsRequired egenskap som kan tilldelas värdet false för medlemmar som läggs till i nya versioner av ett datakontrakt som inte fanns i tidigare versioner, vilket gör att program med den nyare versionen av kontraktet kan bearbeta tidigare versioner.
Genom att ett datakontrakt implementerar IExtensibleDataObject gränssnittet kan man tillåta DataContractSerializer att medlemmar som definierats i nyare versioner av ett datakontrakt skickas via program med tidigare versioner av kontraktet.
Trots alla skillnader är XML-koden som XmlSerializer serialiserar en typ som standard semantiskt identisk med xml-koden som DataContractSerializer serialiserar en typ i, förutsatt att namnområdet för XML uttryckligen definieras. Följande klass, som har attribut för användning med båda serialiserarna, översätts till semantiskt identisk XML av XmlSerializer och av 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;
}
Windows Software Development Kit (SDK) innehåller ett kommandoradsverktyg som kallas ServiceModel Metadata Utility Tool (Svcutil.exe). Precis som det xsd.exe verktyg som används med ASP.NET webbtjänster kan Svcutil.exe generera definitioner av .NET-datatyper från XML-schema. Typerna är datakontrakt om DataContractSerializer kan generera XML i det format som definieras av XML-schemat. Annars är de avsedda för serialisering med hjälp av XmlSerializer. Svcutil.exe kan också generera ett XML-schema från datakontrakt med hjälp av dess dataContractOnly
växel.
Kommentar
Även om ASP.NET webbtjänster använder XmlSerializerkompatibilitetsläget , och WCF ASP.NET gör att WCF-tjänster efterliknar beteendet för ASP.NET webbtjänster, begränsar inte alternativet ASP.NET kompatibilitet en till att använda XmlSerializer. Man kan fortfarande använda DataContractSerializer med tjänster som körs i ASP.NET kompatibilitetsläge.
Tjänstutveckling
För att utveckla en tjänst med hjälp av ASP.NET har det varit vanligt att lägga WebService till attributet i en klass och WebMethodAttribute till någon av den klassens metoder som ska vara drift av tjänsten:
[WebService]
public class Service : T:System.Web.Services.WebService
{
[WebMethod]
public string Echo(string input)
{
return input;
}
}
ASP.NET 2.0 introducerade alternativet att lägga till attributet WebService och WebMethodAttribute till ett gränssnitt i stället för till en klass och skriva en klass för att implementera gränssnittet:
[WebService]
public interface IEcho
{
[WebMethod]
string Echo(string input);
}
public class Service : IEcho
{
public string Echo(string input)
{
return input;
}
}
Att använda det här alternativet är att föredra eftersom gränssnittet med WebService attributet utgör ett kontrakt för de åtgärder som utförs av tjänsten som kan återanvändas med olika klasser som kan implementera samma kontrakt på olika sätt.
En WCF-tjänst tillhandahålls genom att definiera en eller flera WCF-slutpunkter. En slutpunkt definieras av en adress, en bindning och ett tjänstkontrakt. Adressen definierar var tjänsten finns. Bindningen anger hur du kommunicerar med tjänsten. Tjänstkontraktet definierar de åtgärder som tjänsten kan utföra.
Tjänstkontraktet definieras vanligtvis först genom att lägga till ServiceContractAttribute och OperationContractAttribute i ett gränssnitt:
[ServiceContract]
public interface IEcho
{
[OperationContract]
string Echo(string input);
}
ServiceContractAttribute Anger att gränssnittet definierar ett WCF-tjänstkontrakt och OperationContractAttribute anger vilka, om några, av metoderna i gränssnittet som definierar driften av tjänstkontraktet.
När ett tjänstkontrakt har definierats implementeras det i en klass genom att klassen implementerar gränssnittet som tjänstkontraktet definieras med:
public class Service : IEcho
{
public string Echo(string input)
{
return input;
}
}
En klass som implementerar ett tjänstkontrakt kallas för en tjänsttyp i WCF.
Nästa steg är att associera en adress och en bindning med en tjänsttyp. Detta görs vanligtvis i en konfigurationsfil, antingen genom att redigera filen direkt eller med hjälp av en konfigurationsredigerare som tillhandahålls med WCF. Här är ett exempel på en konfigurationsfil.
<?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>
Bindningen anger uppsättningen protokoll för kommunikation med programmet. I följande tabell visas de systembaserade bindningar som representerar vanliga alternativ.
Name | Syfte |
---|---|
BasicHttpBinding | Samverkan med webbtjänster och klienter som stöder WS-BasicProfile 1.1 och Basic Security Profile 1.0. |
WSHttpBinding | Samverkan med webbtjänster och klienter som stöder WS-*-protokoll via HTTP. |
WSDualHttpBinding | Duplex HTTP-kommunikation, genom vilken mottagaren av ett första meddelande inte svarar direkt till den första avsändaren, men kan överföra valfritt antal svar under en tidsperiod genom att använda HTTP i enlighet med WS-* protokoll. |
WSFederationBinding | HTTP-kommunikation, där åtkomst till resurser i en tjänst kan styras baserat på autentiseringsuppgifter som utfärdats av en explicit identifierad autentiseringsprovider. |
NetTcpBinding | Säker, tillförlitlig och högpresterande kommunikation mellan WCF-programvaruentiteter i ett nätverk. |
NetNamedPipeBinding | Säker, tillförlitlig och högpresterande kommunikation mellan WCF-programvaruentiteter på samma dator. |
NetMsmqBinding | Kommunikation mellan WCF-programvaruentiteter med hjälp av MSMQ. |
MsmqIntegrationBinding | Kommunikation mellan en WCF-programvaruentitet och en annan programvaruentitet med hjälp av MSMQ. |
NetPeerTcpBinding | Kommunikation mellan WCF-programvaruentiteter med hjälp av Peer-to-Peer-nätverk i Windows. |
Den systembaserade bindningen, BasicHttpBinding, innehåller den uppsättning protokoll som stöds av ASP.NET webbtjänster.
Anpassade bindningar för WCF-program definieras enkelt som samlingar av de bindningselementklasser som WCF använder för att implementera enskilda protokoll. Nya bindningselement kan skrivas för att representera ytterligare protokoll.
Det interna beteendet för tjänsttyper kan justeras med hjälp av egenskaperna för en grupp klasser som kallas beteenden. ServiceBehaviorAttribute Här används klassen för att ange att tjänsttypen ska vara flertrådad.
[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Multiple)]
public class DerivativesCalculatorServiceType: IDerivativesCalculator
Vissa beteenden, till exempel ServiceBehaviorAttribute, är attribut. Andra, de med egenskaper som administratörer vill ange, kan ändras i konfigurationen av ett program.
I programmeringstjänsttyper används OperationContext ofta klassen. Dess statiska Current egenskap ger åtkomst till information om kontexten där en åtgärd körs. OperationContext liknar både klasserna HttpContext och ContextUtil .
Värd
ASP.NET webbtjänster kompileras till en klassbibliotekssammansättning. En fil med namnet tjänstfilen tillhandahålls som har tillägget .asmx och innehåller ett @ WebService
direktiv som identifierar klassen som innehåller koden för tjänsten och sammansättningen där den finns.
<%@ WebService Language="C#" Class="Service,ServiceAssembly" %>
Tjänstfilen kopieras till en ASP.NET programrot i Internet Information Services (IIS) och sammansättningen kopieras till underkatalogen \bin för programroten. Programmet är sedan tillgängligt med hjälp av den enhetliga resurslokaliseraren (URL) för tjänstfilen i programroten.
WCF-tjänster kan enkelt hanteras i IIS 5.1 eller 6.0, Windows Process Activation Service (WAS) som tillhandahålls som en del av IIS 7.0 och i alla .NET-program. För att vara värd för en tjänst i IIS 5.1 eller 6.0 måste tjänsten använda HTTP som kommunikationstransportprotokoll.
Använd följande steg för att vara värd för en tjänst i IIS 5.1, 6.0 eller inom WAS:
Kompilera tjänsttypen till en klassbibliotekssammansättning.
Skapa en tjänstfil med ett .svc-tillägg med ett
@ ServiceHost
direktiv för att identifiera tjänsttypen:<%@ServiceHost language="c#" Service="MyService" %>
Kopiera tjänstfilen till en virtuell katalog och sammansättningen till underkatalogen \bin för den virtuella katalogen.
Kopiera konfigurationsfilen till den virtuella katalogen och ge den namnet Web.config.
Programmet är sedan tillgängligt med hjälp av URL:en för tjänstfilen i programroten.
Om du vill vara värd för en WCF-tjänst i ett .NET-program kompilerar du tjänsttypen till en klassbibliotekssammansättning som refereras av programmet och programmerar programmet att vara värd för tjänsten med hjälp av ServiceHost -klassen. Följande är ett exempel på den grundläggande programmering som krävs:
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();
}
Det här exemplet visar hur adresser för ett eller flera transportprotokoll anges i konstruktionen av en ServiceHost. Dessa adresser kallas för basadresser.
Adressen som anges för en slutpunkt för en WCF-tjänst är en adress i förhållande till en basadress för slutpunktens värd. Värden kan ha en basadress för varje kommunikationstransportprotokoll. I exempelkonfigurationen i föregående konfigurationsfil använder den BasicHttpBinding valda för slutpunkten HTTP som transportprotokoll, så adressen till slutpunkten, EchoService
, är relativ till värdens HTTP-basadress. När det gäller värden i föregående exempel är http://www.contoso.com:8000/
HTTP-basadressen . För en tjänst som finns i IIS eller WAS är basadressen URL:en till tjänstens tjänstfil.
Endast tjänster som finns i IIS eller WAS, och som är konfigurerade med HTTP som transportprotokoll exklusivt, kan göras för att använda alternativet WCF ASP.NET kompatibilitetsläge. Följande steg krävs för att aktivera det alternativet.
Programmeraren måste lägga till AspNetCompatibilityRequirementsAttribute attributet till tjänsttypen och ange att ASP.NET kompatibilitetsläge antingen tillåts eller krävs.
[System.ServiceModel.Activation.AspNetCompatibilityRequirements( RequirementsMode=AspNetCompatibilityRequirementsMode.Require)] public class DerivativesCalculatorServiceType: IDerivativesCalculator
Administratören måste konfigurera programmet så att det använder ASP.NET kompatibilitetsläge.
<configuration> <system.serviceModel> <services> […] </services> <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/> </system.serviceModel> </configuration>
WCF-program kan också konfigureras för att använda .asmx som tillägg för sina tjänstfiler i stället för .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>
Det alternativet kan spara dig från att behöva ändra klienter som är konfigurerade att använda URL:er för .asmx-tjänstfiler när du ändrar en tjänst för att använda WCF.
Klientutveckling
Klienter för ASP.NET webbtjänster genereras med kommandoradsverktyget WSDL.exe, som tillhandahåller URL:en för .asmx-filen som indata. Motsvarande verktyg som tillhandahålls av WCF är ServiceModel Metadata Utility Tool (Svcutil.exe). Den genererar en kodmodul med definitionen av tjänstkontraktet och definitionen av en WCF-klientklass. Den genererar också en konfigurationsfil med tjänstens adress och bindning.
Vid programmering av en klient för en fjärrtjänst är det vanligtvis lämpligt att programmera enligt ett asynkront mönster. Koden som genereras av verktyget WSDL.exe tillhandahåller alltid både ett synkront och asynkront mönster som standard. Koden som genereras av Verktyget för ServiceModel-metadata (Svcutil.exe) kan ange för endera mönstret. Den tillhandahåller synkront mönster som standard. Om verktyget körs med växeln /async
tillhandahåller den genererade koden det asynkrona mönstret.
Det finns ingen garanti för att namn i WCF-klientklasserna som genereras av ASP.NET:s WSDL.exe-verktyg som standard matchar namnen i WCF-klientklasser som genereras av verktyget Svcutil.exe. I synnerhet är namnen på egenskaperna för klasser som måste serialiseras med hjälp av XmlSerializer som standard givet suffixegenskapen i koden som genereras av verktyget Svcutil.exe, vilket inte är fallet med verktyget WSDL.exe.
Meddelanderepresentation
Sidhuvudena för SOAP-meddelanden som skickas och tas emot av ASP.NET webbtjänster kan anpassas. En klass härleds från SoapHeader för att definiera rubrikens struktur, och sedan används den SoapHeaderAttribute för att indikera förekomsten av huvudet.
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;
}
}
WCF innehåller attributen , MessageContractAttribute, MessageHeaderAttributeoch MessageBodyMemberAttribute för att beskriva strukturen för SOAP-meddelanden som skickas och tas emot av en tjänst.
[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);
}
Den här syntaxen ger en explicit representation av meddelandenas struktur, medan strukturen för meddelanden är underförstådd av koden för en ASP.NET webbtjänst. I den ASP.NET syntaxen representeras även meddelandehuvuden som egenskaper för tjänsten, till exempel ProtocolHeader
egenskapen i föregående exempel, medan de i WCF-syntaxen representeras mer exakt som egenskaper för meddelanden. WCF tillåter också att meddelandehuvuden läggs till i konfigurationen av slutpunkter.
<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>
Med det här alternativet kan du undvika alla referenser till infrastrukturella protokollhuvuden i koden för en klient eller tjänst: rubrikerna läggs till i meddelanden på grund av hur slutpunkten konfigureras.
Tjänstbeskrivning
Om du utfärdar en HTTP GET-begäran för .asmx-filen för en ASP.NET-webbtjänst med frågan orsakar WSDL ASP.NET att generera WSDL för att beskriva tjänsten. Den returnerar WSDL som svar på begäran.
ASP.NET 2.0 gjorde det möjligt att verifiera att en tjänst är kompatibel med Basic Profile 1.1 i Web Services-Interoperability Organization (WS-I) och att infoga ett anspråk på att tjänsten är kompatibel med dess WSDL. Detta görs med hjälp av parametrarna ConformsTo
och EmitConformanceClaims
för attributet WebServiceBindingAttribute .
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(
ConformsTo = WsiProfiles.BasicProfile1_1,
EmitConformanceClaims=true)]
public interface IEcho
Den WSDL som ASP.NET genererar för en tjänst kan anpassas. Anpassningar görs genom att skapa en härledd klass av ServiceDescriptionFormatExtension för att lägga till objekt i WSDL.
När en HTTP GET-begäran utfärdas med frågan WSDL för .svc-filen för en WCF-tjänst med en HTTP-slutpunkt i IIS 51, 6.0 eller WAS, får WCF att svara med WSDL för att beskriva tjänsten. Att utfärda en HTTP GET-begäran med frågan WSDL till HTTP-basadressen för en tjänst som finns i ett .NET-program har samma effekt om httpGetEnabled är inställt på true.
WCF svarar dock också på WS-MetadataExchange-begäranden med WSDL som genereras för att beskriva en tjänst. ASP.NET webbtjänster har inte inbyggt stöd för WS-MetadataExchange-begäranden.
WSDL som WCF genererar kan anpassas i stor utsträckning. Klassen ServiceMetadataBehavior tillhandahåller vissa funktioner för att anpassa WSDL. WCF kan också konfigureras för att inte generera WSDL, utan i stället för att använda en statisk WSDL-fil vid en viss URL.
<behaviors>
<behavior name="DescriptionBehavior">
<metadataPublishing
enableMetadataExchange="true"
enableGetWsdl="true"
enableHelpPage="true"
metadataLocation=
"http://localhost/DerivativesCalculatorService/Service.WSDL"/>
</behavior>
</behaviors>
Undantagshantering
I ASP.NET webbtjänster returneras ohanterade undantag till klienter som SOAP-fel. Du kan också uttryckligen utlösa instanser av SoapException klassen och ha mer kontroll över innehållet i SOAP-felet som skickas till klienten.
I WCF-tjänster returneras inte ohanterade undantag till klienter som SOAP-fel för att förhindra att känslig information oavsiktligt exponeras genom undantagen. En konfigurationsinställning anges för att ohanterade undantag ska returneras till klienter i syfte att felsöka.
Om du vill returnera SOAP-fel till klienter kan du utlösa instanser av den generiska typen, FaultException<TDetail>, med datakontraktstypen som allmän typ. Du kan också lägga till FaultContractAttribute attribut till åtgärder för att ange de fel som en åtgärd kan ge.
[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);
}
Detta resulterar i att eventuella fel annonseras i WSDL för tjänsten, vilket gör det möjligt för klientprogram programmerare att förutse vilka fel som kan uppstå till följd av en åtgärd och skriva lämpliga catch-instruktioner.
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);
}
Tillståndshantering
Klassen som används för att implementera en ASP.NET webbtjänst kan härledas från WebService.
public class Service : WebService, IEcho
{
public string Echo(string input)
{
return input;
}
}
I så fall kan klassen programmeras att använda basklassens WebService kontextegenskap för att få åtkomst till ett HttpContext objekt. Objektet HttpContext kan användas för att uppdatera och hämta programtillståndsinformation med hjälp av dess programegenskap och kan användas för att uppdatera och hämta information om sessionstillstånd med hjälp av dess sessionsegenskap.
ASP.NET ger betydande kontroll över var sessionstillståndsinformationen som används med hjälp av sessionsegenskapen HttpContext för faktiskt lagras. Den kan lagras i cookies, i en databas, i den aktuella serverns minne eller i minnet på en utsedd server. Valet görs i tjänstens konfigurationsfil.
WCF tillhandahåller utökningsbara objekt för tillståndshantering. Utökningsbara objekt är objekt som implementerar IExtensibleObject<T>. De viktigaste utökningsbara objekten är ServiceHostBase och InstanceContext. ServiceHostBase
gör att du kan upprätthålla tillstånd som alla instanser av alla tjänsttyper på samma värd kan komma åt, samtidigt InstanceContext
som du kan underhålla tillstånd som kan nås av kod som körs inom samma instans av en tjänsttyp.
Här har tjänsttypen , TradingSystem
en ServiceBehaviorAttribute som anger att alla anrop från samma WCF-klientinstans dirigeras till samma instans av tjänsttypen.
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class TradingSystem: ITradingService
Klassen , DealData
, definierar tillstånd som kan nås av valfri kod som körs i samma instans av en tjänsttyp.
internal class DealData: IExtension<InstanceContext>
{
public string DealIdentifier = null;
public Trade[] Trades = null;
}
I koden för den tjänsttyp som implementerar en av åtgärderna i tjänstkontraktet läggs ett DealData
tillståndsobjekt till i tillståndet för den aktuella instansen av tjänsttypen.
string ITradingService.BeginDeal()
{
string dealIdentifier = Guid.NewGuid().ToString();
DealData state = new DealData(dealIdentifier);
OperationContext.Current.InstanceContext.Extensions.Add(state);
return dealIdentifier;
}
Tillståndsobjektet kan sedan hämtas och ändras av koden som implementerar en annan av tjänstkontraktets åtgärder.
void ITradingService.AddTrade(Trade trade)
{
DealData dealData = OperationContext.Current.InstanceContext.Extensions.Find<DealData>();
dealData.AddTrade(trade);
}
Medan ASP.NET ger kontroll över var tillståndsinformation i HttpContext klassen faktiskt lagras, ger WCF, åtminstone i sin ursprungliga version, ingen kontroll över var utökningsbara objekt lagras. Det är det allra bästa skälet till att välja ASP.NET kompatibilitetsläge för en WCF-tjänst. Om konfigurerbar tillståndshantering är absolut nödvändigt kan du välja ASP.NET kompatibilitetsläget så att du kan använda klassens faciliteter HttpContext exakt som de används i ASP.NET och även konfigurera var tillståndsinformation som hanteras med hjälp HttpContext av klassen lagras.
Säkerhet
Alternativen för att skydda ASP.NET webbtjänster är de för att skydda alla IIS-program. Eftersom WCF-program kan hanteras inte bara i IIS utan även inom alla körbara .NET-program måste alternativen för att skydda WCF-program göras oberoende av IIS-anläggningarna. De faciliteter som tillhandahålls för ASP.NET webbtjänster är dock också tillgängliga för WCF-tjänster som körs i ASP.NET kompatibilitetsläge.
Säkerhet: Autentisering
IIS tillhandahåller funktioner för att styra åtkomsten till program genom vilka du kan välja anonym åtkomst eller en mängd olika autentiseringslägen: Windows-autentisering, sammanfattad autentisering, grundläggande autentisering och .NET Passport-autentisering. Alternativet Windows-autentisering kan användas för att styra åtkomsten till ASP.NET webbtjänster. Men när WCF-program finns i IIS måste IIS konfigureras för att tillåta anonym åtkomst till programmet, så att autentiseringen kan hanteras av själva WCF, vilket stöder Windows-autentisering bland olika andra alternativ. De andra alternativen som är inbyggda är användarnamnstoken, X.509-certifikat, SAML-token och CardSpace-kort, men anpassade autentiseringsmekanismer kan också definieras.
Säkerhet: Personifiering
ASP.NET tillhandahåller ett identitetselement med vilket en ASP.NET webbtjänst kan göras för att personifiera en viss användare eller beroende på vilken användares autentiseringsuppgifter som tillhandahålls med den aktuella begäran. Det elementet kan användas för att konfigurera personifiering i WCF-program som körs i ASP.NET kompatibilitetsläge.
WCF-konfigurationssystemet tillhandahåller ett eget identitetselement för att utse en viss användare att personifiera. WCF-klienter och -tjänster kan också konfigureras separat för personifiering. Klienter kan konfigureras för att personifiera den aktuella användaren när de skickar begäranden.
<behaviors>
<behavior name="DerivativesCalculatorClientBehavior">
<clientCredentials>
<windows allowedImpersonationLevel="Impersonation"/>
</clientCredentials>
</behavior>
</behaviors>
Tjänståtgärder kan konfigureras för att personifiera den användares autentiseringsuppgifter som tillhandahålls med den aktuella begäran.
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public void Receive(Message input)
Säkerhet: Auktorisering med hjälp av åtkomstkontrollistor
Åtkomstkontrollistor (ACL: er) kan användas för att begränsa åtkomsten till .asmx-filer. ACL:er på WCF .svc-filer ignoreras dock förutom i ASP.NET kompatibilitetsläge.
Säkerhet: Rollbaserad auktorisering
Alternativet IIS Windows-autentisering kan användas tillsammans med auktoriseringselementet som tillhandahålls av ASP.NET konfigurationsspråk för att underlätta rollbaserad auktorisering för ASP.NET webbtjänster baserat på de Windows-grupper som användarna har tilldelats. ASP.NET 2.0 infördes en mer allmän rollbaserad auktoriseringsmekanism: rollleverantörer.
Rollprovidrar är klasser som alla implementerar ett grundläggande gränssnitt för att fråga om de roller som en användare har tilldelats, men varje rollprovider vet hur man hämtar den informationen från en annan källa. ASP.NET 2.0 tillhandahåller en rollprovider som kan hämta rolltilldelningar från en Microsoft SQL Server-databas och en annan som kan hämta rolltilldelningar från Windows Server 2003 Authorization Manager.
Rollprovidermekanismen kan faktiskt användas oberoende av ASP.NET i alla .NET-program, inklusive ett WCF-program. Följande exempelkonfiguration för ett WCF-program visar hur användningen av en ASP.NET rollprovider är ett alternativ som väljs med hjälp av 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>
Säkerhet: Anspråksbaserad auktorisering
En av de viktigaste nyheterna i WCF är dess grundliga stöd för att auktorisera åtkomst till skyddade resurser baserat på anspråk. Anspråk består till exempel av en typ, en rättighet och ett värde, ett körkort. Det gör en uppsättning påståenden om bäraren, varav en är innehavarens födelsedatum. Typen av anspråk är födelsedatum, medan anspråkets värde är förarens födelsedatum. Den rättighet som ett anspråk ger innehavaren anger vad innehavaren kan göra med anspråkets värde. När det gäller kravet på förarens födelsedatum är rätten innehav: föraren har det födelsedatumet men kan till exempel inte ändra det. Anspråksbaserad auktorisering omger rollbaserad auktorisering, eftersom roller är en typ av anspråk.
Auktorisering baserad på anspråk utförs genom att jämföra en uppsättning anspråk med åtkomstkraven för åtgärden och, beroende på resultatet av jämförelsen, bevilja eller neka åtkomst till åtgärden. I WCF kan du ange en klass som ska användas för att köra anspråksbaserad auktorisering, återigen genom att tilldela ett värde till ServiceAuthorizationManager
egenskapen ServiceAuthorizationBehaviorför .
<behaviors>
<behavior name='ServiceBehavior'>
<serviceAuthorization
serviceAuthorizationManagerType=
'Service.AccessChecker, Service' />
</behavior>
</behaviors>
Klasser som används för att köra anspråksbaserad auktorisering måste härledas från ServiceAuthorizationManager, som bara har en metod att åsidosätta, AccessCheck()
. WCF anropar den metoden när en åtgärd av tjänsten anropas och tillhandahåller ett OperationContext objekt som har anspråken för användaren i dess ServiceSecurityContext.AuthorizationContext
egenskap. WCF utför arbetet med att samla in anspråk om användaren från den säkerhetstoken som användaren angav för autentisering, vilket lämnar uppgiften att utvärdera om dessa anspråk räcker för åtgärden i fråga.
Att WCF automatiskt sammanställer anspråk från någon typ av säkerhetstoken är en mycket viktig innovation, eftersom den gör koden för auktorisering baserad på anspråken helt oberoende av autentiseringsmekanismen. Auktorisering med hjälp av ACL:er eller roller i ASP.NET är däremot nära kopplat till Windows-autentisering.
Säkerhet: Konfidentialitet
Konfidentialiteten för meddelanden som utbyts med ASP.NET webbtjänster kan säkerställas på transportnivå genom att konfigurera programmet i IIS för att använda HTTPS (Secure Hypertext Transfer Protocol). Samma sak kan göras för WCF-program som finns i IIS. WCF-program som finns utanför IIS kan dock också konfigureras för att använda ett säkert transportprotokoll. Ännu viktigare är att WCF-program också kan konfigureras för att skydda meddelandena innan de transporteras med hjälp av WS-Security-protokollet. Genom att skydda bara brödtexten i ett meddelande med hjälp av WS-Security kan det överföras konfidentiellt mellan mellanhänder innan det når slutmålet.
Globalisering
Med konfigurationsspråket ASP.NET kan du ange kulturen för enskilda tjänster. WCF stöder inte den konfigurationsinställningen förutom i ASP.NET kompatibilitetsläge. Om du vill lokalisera en WCF-tjänst som inte använder ASP.NET kompatibilitetsläge kompilerar du tjänsttypen till kulturspecifika sammansättningar och har separata kulturspecifika slutpunkter för varje kulturspecifik sammansättning.