Upload
reed-dale
View
40
Download
5
Tags:
Embed Size (px)
DESCRIPTION
2006. Välkommen till Sommarkollo 2006 Windows Communication Foudnation. Windows Communication Foundation. Johan Lindfors. Agenda. Vad är WCF Programmera WCF Kontrakt ”Hostning” och uppträdanden Bindningar och metadata Andra koncept Migrering eller integration Monitorering Säkerhet - PowerPoint PPT Presentation
Citation preview
1
Välkommen till Sommarkollo
2006Windows Communication
Foudnation
2006
Windows Communication FoundationJohan Lindfors
Agenda Vad är WCF Programmera WCF
Kontrakt ”Hostning” och uppträdanden Bindningar och metadata
Andra koncept Migrering eller integration Monitorering Säkerhet Transaktioner Köhantering
Hur ser det ut idag?
Remoting
ASMX / WSE
DCOM
System.Messaging
Enterprise Services
Microsoft
Sockets
RMI
JAX-RPC
CORBA
JMS
EJB
J2EE
Sockets
WCF byggstenar Förenar teknikerna för distribuerad
kommunikation ”On-machine”, ”Cross-machine”,
”Cross-Internet”
Brett stöd för WS-* specifikationerna Kompatibelt med existerande
tekniker från Microsoft
Förenklar utvecklingen av löst kopplade tjänster
Konfigurationsbaserad kommunikation
Enhetlig
Interoperabilitet
Tjänsteorienterat
En samlingsklass för olika typer
Lagra instanser i strukturen
Hämta instanser
public class Stack{ object[] items; public void Push(object item){…} public object Pop(){…}}
Lite om generiska klasser
Stack stack = new Stack();int i;string s = null;stack.Push(i);stack.Push(s); // Inkonsekvens i typer!
string s = (string)stack.Pop(); //Paying for cast
Hur kul är det här egentligen?public class IntegerStack{ int[] items; public void Push(int item){…} public int Pop(){…}}
Utan generiska klasser
public class StringStack{ string[] items; public void Push(string item){…} public string Pop(){…}}
Mallen
Användningen
public class Stack<T> //T är generisk typparameter{ T[] items; public void Push(T item){…} public T Pop(){…}}
Med generiska klasser
Stack<int> integerStack = new Stack<int>(); integerStack.Push(1);
Stack<string> stringStack = new Stack<string>();stringStack.Push(“Hello, World!”);
Flera typer vid definition
Använda aliaser
Begränsningar
public class Point<X,Y>{…}
Point<int,int> point = null;
Detaljer…
using IntegerPoint = Point<int,int>;IntegerPoint point = null;
public class Stack<T> where T: IComparable
public class Node<T> where T: new() { private T item = new T();}
Kan bara konvertera typparametrar till ”interface”
Ärva från en generisk klass
class MyClass<T>{ void SomeMethod(T t) { ISomeInterface something = (ISomeInterface)t; SomeClass somethingElse = (SomeClass)t; //Error! }}
Mer detaljer…
public BaseClass<T>{…}
public ChildClass: BaseClass<string> {…}
Generiska metoderpublic class MyClass{ public void MyMethod<T>(T t) { … }}
MyClass instance = new MyClass();instance.MyMethod(3);instance.MyMethod(“Hello, World”);
Mer detaljer…
Klient Tjänst
Klienter och tjänster
Klient Tjänst
“Endpoints”
EndpointEndpoint
Endpoint
Endpoint
Endpoints exponerar funktionalitet
Klient Tjänst
Adress, Bindning, Kontrakt
ABC
CBA
CBA
CBA
Endpoints exponerar funktionalitet Adress beskriver VART! Bindning beskriver HUR! Kontrakt beskriver VAD!
WSDLKlient Tjänst
Metadata
ABC
CBA
CBA
CBA
Endpoints exponerar funktionalitet Adress beskriver VART! Bindning beskriver HUR! Kontrakt beskriver VAD!
WSDL beskriver ”endpoints”
WSDLKlient Tjänst
Uppträdanden
Uppträdanden beskriver exempelvis Instansiering och aktivering Sessionshantering Transaktioner
ABC
CBA
CBA
CBAU UU
[ServiceContract]public interface IHello{ [OperationContract] string Hello(string name);}
Definition av kontrakt och tjänst
public class HelloService : IHello{ public string Hello(string name) { return "Hello, " + name; }}
Kontrakt
Implementation
I en egen applikation
IIS/WAS (http://localhost/HelloService/HelloService.svc)
class HelloHost{ static void Main(string[] args) { ServiceHost host = new ServiceHost(typeof(HelloService)); host.Open(); // Wait until done accepting connections Console.ReadLine(); host.Close(); }}
Hostning av tjänsten
<%@ ServiceHost Language=“C#” Service=“HelloService” %>
Konfiguration<?xml version="1.0" encoding="utf-8" ?><configuration> <system.serviceModel> <services> <service name="HelloService"> <endpoint address="http://localhost/HelloService" binding="basicHttpBinding" contract="IHello" /> </service> </services> </system.serviceModel></configuration>
Kod
Konfiguration
static void Main() { IHello proxy = new ChannelFactory<IHello> ("HelloEndpoint").CreateChannel(); string r = proxy.Hello("Beat"); Console.WriteLine(r);}
Implementera klienten
<system.serviceModel> <client> <endpoint name="HelloEndpoint" address="http://localhost/HelloService" binding="basicHttpBinding" contract="IHello" /> </client></system.serviceModel>
Arkitektur för dagen
Store
ASP.NETWebApplication
StoreService
AdminService
AdminClient
WindowsApplication
AdminServiceCallback
StoreClient
WindowsApplication
Shipments
WindowsApplication
ShipmentService
Customers
ASP.NETWebApplicationCustomerService
Orders
ASP.NETWebApplication OrderService
Inventory
ASP.NETWebApplication
InventoryServiceWS
Agenda Vad är WCF Programmera WCF
Kontrakt ”Hostning” och uppträdanden Bindningar och metadata
Andra koncept Migrering eller integration Monitorering Säkerhet Transaktioner Köhantering
Kontrakt Strukturella – ”Structural”
[DataContract] [MessageContract]
Agerande – ”Behavioral” [ServiceContract] [OperationContract] [FaultContract]
Oberoende av OO-åtkomstnivåer
[DataContract]
using System.Runtime.Serialization;
[DataContract(Name="PersonType")]public class Person {
[DataMember]public string name;
[DataMember(Name="AgeProperty")]private int age;
[DataMember]float salary;
int positionCode;}
Hantering av samlingar
[DataContract]
[DataContract]public class LibraryCatalog{ [DataMember] System.Collections.Hashtable catalog;}
Använda [KnownType]-attributet
[DataContract]
[DataContract][KnownType(typeof(Book))][KnownType(typeof(Magazine))]public class LibraryCatalog{
[DataMember]System.Collections.Hashtable catalog;
}
[DataContract]public class Book{…}[DataContract]public class Magazine{…}
Vid osäkerhet av datatyper
[DataContract]
[DataContract][KnownType(typeof(Book))][KnownType(typeof(Magazine))]public class PublishedItem{
[DataMember]object catalog;[DataMember]DateTime publicationDate;
}
[DataContract]public class Book{…}[DataContract]public class Magazine{…}
Versionshantering
[DataContract]
[DataContract]public class Car{ [DataMember(IsRequired = true)] public string Model; [DataMember(IsRequired = false)] //default public int HorsePower;}
För skräddarsydda ”SOAP-headers” Vilket inte rekommenderas
[MessageContract]
[DataContract]public class PurchaseOrder {...}
[MessageContract]public class PurchaseOrderMessage{ [MessageHeader] public int Number; [MessageBody(Order = 1)] public PurchaseOrder Order;}
Kontrollerar hur strukturella kontrakt serialiseras
[ServiceContract]
[ServiceContract][DataContractFormat( Style=OperationFormatStyle.Document)] //Or Rpcpublic interface IOrderEntry {...}
[ServiceContract][XmlSerializerFormat( Style=OperationFormatStyle.Document, Use=OperationFormatUse.Literal)] //Or Encodedpublic interface IOrderEntry {...}
Duplex
[ServiceContract]
[ServiceContract(Session = true, CallbackContract = typeof(IOrderEntryCallback))]public interface IOrderEntry{ [OperationContract(IsOneWay = true)] void PlaceOrder(PurchaseOrder order);}
[ServiceContract]public interface IOrderEntryCallback{ [OperationContract(IsOneWay = true)] void PlaceOrderCompleted( PurchaseOrderStatus orderStatus);}
Implementation En implementation av ett interface Klassen kallas då ”Service Type”
[ServiceContract]
[ServiceContract]public interface IOrderEntry { [OperationContract(IsOneWay = true)] void PlaceOrder(PurchaseOrder order);}
internal class OrderEntryService : IOrderEntry{ void IOrderEntry.PlaceOrder(PurchaseOrder order) { //Your code goes here }}
Exponera metoder
Egenskapen ”Action”
[ServiceContract]public interface IOrderEntry{ [OperationContract(IsOneWay = true)] void PlaceOrder(PurchaseOrder order);}
[OperationContract]
[ServiceContract]public interface IOrderEntry{[OperationContract( Action="http://contoso.com/GetOrder", ReplyAction="http://contoso.com/GetOrderReply")] PurchaseOrder GetOrder(String orderIdentifier);}
Rekommendation Använd Action=”*” som en generell
funktion
[OperationContract]
[ServiceContract]public interface MyContract { [OperationContract(IsOneWay = true, Action="urn:crud:insert")] void ProcessInsertMessage(Message message); [OperationContract(IsOneWay = true, Action="urn:crud:update")] void ProcessUpdateMessage(Message message); [OperationContract(IsOneWay = true, Action="urn:crud:delete")] void ProcessDeleteMessage(Message message); [OperationContract(IsOneWay = true, Action="*")] void ProcessUnrecognizedMessage(Message message); }
Synkront
Asynkront
[ServiceContract]public interface IMath{ [OperationContract] int Add(int I, int j);}
[OperationContract]
[ServiceContract]public interface IMath{ [OperationContract(AsyncPattern = true)] IAsyncResult BeginAdd( int i, int j, AsyncCallback cb, object o); int EndAdd(IAsyncResult result);}
[FaultContract][DataContract]class MyFault { [DataMember] public string Reason = null;}[ServiceContract]public interface IOrderEntry { [OperationContract] [FaultContract(typeof(MyFault))] PurchaseOrder GetOrder(String orderId); }public class OrderEntry: IOrderEntry { public PurchaseOrder GetOrder(string orderId) { try{…}
catch(Exception exception) { MyFault theFault = new MyFault(); theFault.Reason = “Some Reason”; throw new FaultException<MyFault>(theFault); }
}}
På klienten[DataContract(Name="MyFault")]public class ClientFault{
[DataMember]string Reason = null;
}
...
try { PurchaseOrder order = Service.GetOrder(orderId);}catch (FaultException<ClientFault> clientFault) { Console.WriteLine(clientFault.Detail.Reason);}
[FaultContract]
Kod först
Kontrakt först
[ServiceContract]public class OrderEntry { [OperationContract(IsOneWay = true)] public void PlaceOrder(PurchaseOrder order) { return; }}
Programmera kontrakt
[ServiceContract]public interface IOrderEntry { [OperationContract(IsOneWay = true)] void PlaceOrder(PurchaseOrder order);}public class OrderEntry : IOrderEntry { public void PlaceOrder(PurchaseOrder order) { return; }}
WCF och WSDL WSDL kontrakt genereras i flera filer
Använder <wsdl:import.../> Scheman separeras alltid från tjänsten
<wsdl:definitions> <wsdl:portType.../>
<wsdl:binding.../>
<wsdl:service.../><endpoint name="MyServiceEndpoint" bindingNamespace="http://myservice.com/binding"
[ServiceContract(Namespace="urn:gadgets-org")]public interface MyServiceContract {}
[ServiceBehavior(Namespace="urn:my-unique-namespace2")]public class MyService : IMyService
Agenda Vad är WCF Programmera WCF
Kontrakt ”Hostning” och uppträdanden Bindningar och metadata
Andra koncept Migrering eller integration Monitorering Säkerhet Transaktioner Köhantering
I egna applikationer
Hosting - Implementation
[ServiceContract]public interface ILenderService {...}internal class LenderService: ILenderService {...}
public class Program { static void Main(string[] args) { using (ServiceHost host = ServiceHost( typeof(LenderService))) { host.Open(); Console.WriteLine(”Host is active."); Console.ReadLine(); host.Close(); } }}
I hanterad ”Windows Service” Processens livslängd kontrolleras av
OS Inbyggd “Service Control Manager”
Hosting - Implementation
public partial class MyNTService : ServiceBase { private ServiceHost host = null; public MyNTService() { InitializeComponent(); }
protected override void OnStart(string[] args) { this.host = new ServiceHost( typeof(LenderService)); host.Open(); }
protected override void OnStop() { host.Close(); }}
IIS 5.1 och 6 Bara över HTTP
Med WAS HTTP, TCP, NamedPipes
using System.ServiceModel;
namespace MyNamespace{
[ServiceContract]public interface ILender {…}
internal class LenderService: ILender {…}}
Hosting - Implementation
<%@ ServiceHost Language=“C#” Service=“MyNamespace.LenderService” %>
Uppträdanden Vid utveckling
Instansiering ”Concurrency” ”Throttling” ”Transactions”
Vid driftsättning
.PerCall En instans per anrop
.PerSession, .Shareable En instans per session
.Single En instans per tjänst
Instansiering
[ServiceContract] public interface IEcho{ … }
[ServiceBehavior(InstanceContextMode= InstanceContextMode.Single)]internal class MyService: IEcho { …}
.Single Med ytterligare konstruktorer
Instansiering
[ServiceContract]public interface IEcho{ ... }
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]internal class MyService: IEcho { private string myData = null;
private MyService(){} internal MyService(string startUpData){ this.myData=startUpData; } ...}
public class MyHost { MyService service = new MyService(“The initial data”); using(ServiceHost host = new ServiceHost(service)) { ... }}
.PerSession
Instansiering
[ServiceContract][ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]public class Math{ private long sum = 0;
[OperationContract] public int Add(int i, int j) { this.sum = this.sum + i + j; return i + j; } [OperationContract] public long GetTotal() { return this.sum; } [OperationContract] [OperationBehavior(ReleaseInstanceMode = ReleaseInstanceMode.AfterCall)] public void Clear() { this.sum = 0; }}
Kontrollerar trådsäkerhet för ”Service Type” med tre lägen Single (som är grundinställning) Multiple Reentrant
Inte relevant för instansering per anrop
“Concurrency”
[ServiceContract]public interface IEchoContract { ... }
[ServiceBehavior(ConcurrencyMode= ConcurrencyMode.Multiple)]public class EchoService: IEchoContract { ... }
Kan användas för att begränsa last Samtidiga anrop, instanser,
kopplingar
“Throttling”
<behaviors> <behavior> <throttling maxConcurrentCalls="2" maxConnections="10" maxInstances="10"/> </behavior></behaviors>
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]public class MyService { ... }
Agenda Vad är WCF Programmera WCF
Kontrakt ”Hostning” och uppträdanden Bindningar och metadata
Andra koncept Migrering eller integration Monitorering Säkerhet Transaktioner Köhantering
Bindningar En bindning består av
Transport + ”Encoding” + Protokoll
Tre sätt att konfigurera Använd en standard Anpassa en standard Skapa en skräddarsydd
Bindningar En bindning består av
Transport + ”Encoding” + Protokoll
Transport HTTP TCP NamedPipe MSMQ
”Encoding” Text
För bästa interoperabilitet Binary
För bästa prestanda WCF till WCF MTOM
Message Transmission Optimization Protocol
För att bifoga binära tillägg Använder XOP
MTOM ”Encoding” Implementation i WCF
Välj helt enkelt MTOM som ”encoding”
Alla byte[] och strömmar kommer att MTOM’as
<bindings> <wsHttpBinding> <binding name="MTOMBinding" messageEncoding="Mtom"/> </wsHttpBinding></bindings>
Protokoll Kan innehålla
WS-Security WS-ReliableMessaging WS-Coordination och Transaction
Bindningar
Interoperabiliet Säkerhet
SessionTransaktionerDuplex
BasicHttpBinding BP 1.1 T | SWsHttpBinding WS T | S X XWsDualHttpBinding WS S X X XNetTcpBinding .NET T | S X X XNetNamedPipeBinding
.NET T X X X
NetMsmqBinding .NET T | S XCustomBinding * * * * *T = SSL/TLS | S = WS-Security | O = “One-Way Only”
Att välja bindning
BasicHttpBinding
WsHttpBinding
Interop?
Nivå?
Duplex?
WSDualHttpBinding
NetNamedPipeBinding
NetMsmqBinding
NetPeerTcpBinding
NetTcpBinding
Nej
Basic
Nej
Ja
Lokalt?
Köhantering?
P2P?
Nej
Nej
Nej
Ja
Ja
Ja
WS
Ja
Bindningar: Standard<?xml version="1.0" encoding="utf-8" ?><configuration> <system.serviceModel> <services> <service name="MathService"> <endpoint address="http://localhost/MathEndpoint" binding="wsHttpBinding" contract="IMathService" /> </service> </services> </system.serviceModel></configuration>
OBS: Liten bokstav på bindning i konfiguration
Bindningar: Anpassa<configuration> <system.serviceModel> <services> <service name="MathService"> <endpoint address=”http://localhost/MathEndpoint" binding="wsHttpBinding" bindingConfiguration="MTOMOption" contract="IMath"/> </service> </services> <bindings> <wsHttpBinding> <binding name="MTOMOption" messageEncoding="Mtom"/> </wsHttpBinding> </bindings> </system.serviceModel></configuration>
Definera i kod
Bindningar: Skapa egna
public static void Main(string[] args){ ServiceHost host = new ServiceHost(typeof(MathService), "net.tcp://localhost/8080/MathService/");
ReliableSessionBindingElement r = new ReliableSessionBindingElement(); r.AdvancedFlowControl = true;
SecurityBindingElement s = AsymmetricSecurityBindingElement.CreateKerberosBinding();
TcpTransportBindingElement t = new TcpTransportBindingElement(); t.MaxMessageSize = long.MaxValue;
BinaryMessageEncodingBindingElement e = new BinaryMessageEncodingBindingElement();
CustomBinding binding = new CustomBinding(new BindingElement[]{r,s,t,e});
EndpointAddress address = "net.tcp://localhost/8080/Math/"; host.AddEndpoint(typeof(IMath), binding, address);
host.Open();}
Definera i konfiguration
Bindningar: Skapa egna
<?xml version=“1.0” encoding=“UTF-8” ?><configuration> <system.serviceModel> <bindings> <customBinding> <binding name="MyCustomBinding"> <reliableSession enableFlowControl="true"/> <security authenticationMode="Kerberos"/> <binaryMessageEncoding /> <tcpTransport maxReceivedMessageSize=”..." /> </binding> </customBinding> </bindings> </system.serviceModel></configuration>
Adresser Adresser exponerar transportsätt
http://x.se:80/Service/MyEndPoint net.tcp://x.se:8080/Service/
MyEndPoint net.pipe://x.se/Service/MyEndPoint net.msmq://x.se/MyQueue
Per tjänst En basadress per transportsätt
Per “Endpoint” Adressen är relativ till basadressen
class Program { static void Main(string[] args) { using (ServiceHost host = new ServiceHost( typeof(EchoService), new Uri("http://localhost:8000/EchoService"))) { host.Open(); Console.ReadLine(); host.Close();} } }
Adresser
<service name=”EchoService"> <endpoint address="Echo" binding="basicHttpBinding" contract="IEcho"/></service>
Hostning i IIS eller WAS Adressen är URL för .SVC fil Ex:
http://localhost/MyService/Service.svc
Adresser
<configuration> <system.serviceModel> <services> <service name="Program"> <endpoint address="" binding="basicHttpBinding" contract="IEcho"/> </service> </services> </system.serviceModel></configuration>
Med kod, metod 1 One-off “In-line Proxy”
Klienter
using System.ServiceModel;namespace MyNamespace { public interface IEcho { string Echo(string input); }
public class Program { public static void Main(string[] arguments) { IEcho proxy = new ChannelFactory<IEcho> ("EchoService").CreateChannel(); Console.WriteLine(proxy.Echo(”Ping")); ((IChannel)proxy).Close(); } }}
Med kod, metod 2 Återanvändbar “klass-proxy”
Klienter
using System.ServiceModel;[ServiceContract]public interface IEchoService { [OperationContract] string Echo(string input);}
internal class EchoServiceClient: ClientBase<IEchoService>, IEchoService { public EchoServiceClient(string configurationName) :base(configurationName) { } string IEchoService.Echo(string input) { return this.InnerProxy.Echo(input); }}
public class Program { public static void Main(string[] arguments) { EchoServiceClient client = new EchoServiceClient("EchoService"); ((IEchoServiceClient)client).Echo("Hello, World!"); client.Close(); }}
Konfigurationen
Klienter
<system.serviceModel> <client> <endpoint name="EchoService" address=”http://localhost:8000/EchoService/Echo" binding="basicHttpBinding" contract="MyNamespace.IEcho"/> </client></system.serviceModel>
Agenda Vad är WCF Programmera WCF
Kontrakt ”Hostning” och uppträdanden Bindningar och metadata
Andra koncept Migrering eller integration Monitorering Säkerhet Transaktioner Köhantering
Migrering eller samexistens
Sida-vid-sida Uppgradering
Interoperabilitet
using System.Web.Services; public class AccountingOperation{ public string AccountName; public long Amount; }
public class Accounting {
[WebMethod(TransactionOption=TransactionOption.RequiresNew)] public int AddEntry(AccountingOperation debit, AccountingOperation credit) { // Add entry to internal accounting book // return id. }}
using System.ServiceModel;
[ServiceContract(FormatMode=ContractFormatMode.XmlSerializer)]
[OperationContract][OperationBehavior(AutoEnlistTransaction=true)]
//
//
ASMX till WCF
public class Accounting : ServicedComponent{
public void AddCreditEntry(string creditAccount, int creditAmount) { }}
using System.EnterpriseServices;
[ComponentAccessControl][SecureMethod][Transaction(TransactionOption.Required)]
[SecurityRole("Manager")]
using System.ServiceModel;
[ServiceContract]
[OperationContract][OperationBehavior(AutoEnlistTransaction=true)][PrincipalPermission(SecurityAction.Demand, Role="Managers")]
//
//////
//
COM+ till WCF
using Microsoft.Web.Services3;
[WebService]class HelloWorld {
[WebMethod] public string Hello (string text) {
MessageSignature signature = (MessageSignature)RequestSoapContext.Current.Security.Elements[0];if (!signature.SigningToken.Principal.IsInRole ("BUILTIN\Administrators"))
throw new AuthorizationException("Access denied"); return String.Format("Hello, {0}", text); }}
// Konfigurationsförändringar krävs också
[OperationContract][PrincipalPermission(SecurityAction.Demand, null, "BUILTIN\Administrators")]
using System.ServiceModel;
[ServiceContract]
//
//
//
//////////
WSE till WCF
class MyQService { public void ReceiveOrders() { MessageQueue Queue = new MessageQueue(@".\private$\Books"); XmlMessageFormatter formatter = new XmlMessageFormatter( new Type[] { typeof(System.Data.DataSet)}); Queue.Formatter = formatter; System.Messaging.Message msg = null; while((msg= Queue.Receive()) != null) {
DataSet booklist = (DataSet) msg.Body; ProcessOrders(booklist);
} }
Public void ProcessOrder(DataSet BookList) { ... }
}
using System.Messaging;using System.ServiceModel;
[ServiceContract]
[OperationContract(IsOneWay = true)]
//
//
//
//////////////
////
//
MSMQ till WCF
using System.Runtime.Remoting; [Serializable]public class AccountingOperation{ public string AccountName; public long Amount; } public class Accounting { public int AddEntry(AccountingOperation debit, AccountingOperation credit) { // Add entry to internal accounting book // return id. }}
using System.ServiceModel;
[ServiceContract]
[OperationContract]
: MarshalByRefObject
//
//
.NET Remoting till WCF
Agenda Vad är WCF Programmera WCF
Kontrakt ”Hostning” och uppträdanden Bindningar och metadata
Andra koncept Migrering eller integration Monitorering Säkerhet Transaktioner Köhantering
Monitorering Loggning Tracing Performance Counters Event Logging WMI
Loggning<system.serviceModel> <diagnostics> <messageLogging logEntireMessage="true" maxMessagesToLog="300" logMessagesAtServiceLevel="true" logMalformedMessages="true" logMessagesAtTransportLevel="false" /> </diagnostics></system.serviceModel><system.diagnostics> <sources> <source name="System.ServiceModel.MessageLogging"> <listeners> <add name="MyListener" type="System.Diagnostics.XmlWriterTraceListener" initializeData="C:\logs\ClientTraces.e2e" traceOutputOptions="None" /> </listeners> </source> </sources></system.diagnostics>
Tracing Källor
System.Security.Authorization Microsoft.InfoCards.Diagnostics System.IO.Log System.Runtime.Serialization System.ServiceModel Microsoft.TransactionsBridgs.Dtc
Nivåer All, Off Critical, Error, Warning Information, Verbose ActivityTracing
Slå på räknare per service Kan sättas i machine.config
Kan analyseras på fyra nivåer ServiceHost Endpoint Operation (AppDomain)
<configuration> <system.serviceModel> <diagnostics performanceCountersEnabled="true"/> </system.serviceModel></configuration>
“Performance Counters”
Agenda Vad är WCF Programmera WCF
Kontrakt ”Hostning” och uppträdanden Bindningar och metadata
Andra koncept Migrering eller integration Monitorering Säkerhet Transaktioner Köhantering
Säkerhet och WCF Säkerheten i WCF erbjuder två saker
Säker överföring av meddelanden mellan entiteter
Begränsa åtkomst till resurser från entiteter
Entitet Person, företag, applikation
Resurs Fil, tjänst, operation
Säkerhet för meddelanden Konfidentiell Integritet Autentisering Auktorisering
Loggning
Vitsord – “Credentials” Utsagor – “Claims”
Information om en entitet Används för att kontrollera åtkomst
till resuser Utfärdare – “Issuer”
Certifierar utsagor i vitsord Bevis på ägandeskap – ”Proof of
possession” Hur en enitet bevisar sina utsagor
Säkerhetsmodellen i WCF Baseras på vitsord och utsagor
Kan erbjuda önskade krav på säkerhet
Säkert som grundinställning Utom vid interoperabilitet BasicHttpBinding
Konsekvent mellan inställningar (bindningar)
Konsekvent mellan vitsord
Säkerhet på transportnivå Säkerhetskraven erbjuds på
transportlagret Fördelar
Bra prestanda Vanlig implementation Små förändringar
Nackdelar Begränsad uppsättning utsagor Ingen säkerhet utanför “tråden”
Säkerhet på transportnivå<endpoint address="https://localhost/calculator" binding="basicHttpBinding" bindingConfiguration=”SSLBinding" contract="ICalculator" />
<basicHttpBinding> <binding name="SSLBinding"> <security mode="Transport"> <transport clientCredentialType="None"/> </security> </binding></basicHttpBinding>
Säkerhet på meddelanden Säkerhetskraven erbjuds på
meddelandelagret Fördelar
Stöd för fler typer av utsagor Utbyggbart Säkerhet från “början till slut”
Nackdelar Standards och användning
konsolideras fortfarande Viss påverkan på prestandan
Säkerhet på meddelandenivå<endpoint address="http://localhost/calculator" binding=”wsHttpBinding" bindingConfiguration=”WSBinding" contract="ICalculator" />
<wsHttpBinding> <binding name=”WSBinding"> <security mode=”Message"> <message clientCredentialType=”Windows"/> </security> </binding></wsHttpBinding>
“Mixed Mode” Kompromiss mellan säkerhet på
transport- och meddelande-nivån Transportnivån erbjuder
integritet och konfidentiallitet Fördelar för prestandan
Meddelandenivån hanterar utsagor Rika “vitsord”, utbyggbart
“Mixed Mode”<endpoint address="https://localhost/calculator" binding=”wsHttpBinding" bindingConfiguration=”MixedBinding" contract="ICalculator" />
<wsHttpBinding> <binding name=”MixedBinding"> <security mode=” TransportWithMessageCredential"> <message clientCredentialType=”Windows"/> </security> </binding></wsHttpBinding>
Användarnamn/lösenord
Console.WriteLine(" Enter username[domain\\user]:");string username = Console.ReadLine();Console.WriteLine(" Enter password:");string password = Console.ReadLine();
CalculatorProxy wsProxy = new CalculatorProxy();wsProxy.ChannelFactory.Credentials. UserName.UserName = username;wsProxy.ChannelFactory.Credentials. UserName.Password = password;
“Impersonation”[OperationBehavior( Impersonation=ImpersonationOption.Required)]public double Sub(int a, int b){ return a - b;}
public double Add(int a, int b){ using (ServiceSecurityContext.Current. WindowsIdentity.Impersonate()) { return a + b; }}
“PrincipalPermission”[PrincipalPermission(SecurityAction.Demand, Role="Builtin\\Administrators")]public double Mul(int a, int b){ return a * b;}
<behaviors> <behavior name="BuiltinSecurity"> <serviceAuthorization principalPermissionMode="UseWindowsGroups"/> </behavior></behaviors>
Agenda Vad är WCF Programmera WCF
Kontrakt ”Hostning” och uppträdanden Bindningar och metadata
Andra koncept Migrering eller integration Monitorering Säkerhet Transaktioner Köhantering
Transaktioner Atomiska eller kompenserande
Välj mellan koppling eller komplexitet Atomiska transaktioner
Enklare att utveckla Negativ påverkan på prestandan “Tightare”-koppling
Kompenserande aktivitet Mer komplex att utveckla Bättre prestanda “Lösare”-koppling
Välj modell baserat på situationen
Transaktioner
[ServiceContract]public interface IMyContract{ [OperationContract] [TransactionFlow(TransactionFlowOption.Required)] bool Transfer1(Account from, Account to, decimal amount);
[OperationContract] [TransactionFlow(TransactionFlowOption.NotAllowed)] bool Transfer2(Account from, Account to, decimal amount);
}
Delta i en transaktion
Transaktioner
public class MyService: IMyContract{ [OperationBehavior( TransactionScopeRequired = true, TransactionAutoComplete = true)] public bool Transfer1( Account from, Account to, decimal amount) { ... } [OperationBehavior( TransactionScopeRequired = true, TransactionAutoComplete = false)] public bool Transfer2( Account from, Account to, decimal amount) { ... OperationContext.Current.SetTransactionComplete(); } }
Utvecklaren av tjänsten
Transaktioner
TransactionScope transaction;using (scope = new TransactionScope()){ proxyOne.Transfer1(AccountOne, AccountTwo, amount); proxyTwo.Transfer1(AccountThree,AccountFour,amount); UpdateLocalCache(AccountOne, AccountTwo, amount); scope.Complete(); }
Använda transaktioner Klientsidan
Transaktioner
<bindings> <wsHttpBinding> <binding name="SampleBinding“ transactionFlow=“true" /> </binding> </wsHttpBinding></bindings>
Kontroll av transaktioner Administratören av tjänsten
Agenda Vad är WCF Programmera WCF
Kontrakt ”Hostning” och uppträdanden Bindningar och metadata
Andra koncept Migrering eller integration Monitorering Säkerhet Transaktioner Köhantering
Hur fungerar köer?
Meddelande M
edde
land
e
Klient Tjänst
“Queue”“Queue”
Köer Förbättrar tillgängligheten
Döljer åtkomst till tjänst eller nätverk Stöd för utskalning
Flera läsare från en kö Erbjuder lastbalansering
Buffrar meddelanden för senare hantering
Är en av byggstenarna för kompenserande aktiviteter
Hur köer fungerar!
Meddelande Meddelande
Klient Tjänst
“Dead LetterQueue”
“Queue”
“Poison Queue”
“Queue”
“Queue Endpoint”<endpoint address ="net.msmq://MyServer/private/MyQueue/”" binding="netMsmqBinding" bindingConfiguration ="MyQueueBinding" contract="IPurchaseOrder" />
Integrera med ASP.NET HttpContext.Current som i ASMX Värden måste vara IIS 5.1, 6 eller
WAS Bara för transport över HTTP[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)][ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single)]internal class TallyService: ITally { long ITally.Tally(int value) { long? currentTally = (long?)HttpContext.Current.Session["Tally"]; if(currentTally == null)currentTally = 0; currentTally++; HttpContext.Current.Session["Tally"] = currentTally++; return currentTally; }}
Integrera med ASP.NET Slå på i konfigurationen
Web.config<system.serviceModel> <services> <service name="HostedService.TallyService, HostedService"> <endpoint address="" binding="basicHttpBinding" contract="HostedService.ITally, HostedService"/> </service> </services> <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/></system.serviceModel>
Integrera med ASP.NET På klientsidan<system.serviceModel> <client> <endpoint name="TallyService" address="http://x.se/TallyService/Service.svc" binding="customBinding” bindingConfiguration="AllowCookieBinding" contract="HostedService.ITally, Client"/> </client> <bindings> <customBinding> <binding name="AllowCookieBinding"> <httpTransport allowCookies="true"/> </binding> </customBinding> </bindings></system.serviceModel>
“ASP.NET Providers” Medlemskap
Existerar en användare? Har användaren specificerat korrekta
“vitsord”
Rollhantering Tillhör användaren en specifik grupp? Vilka grupper tillhör användaren?
RoleProviderpublic abstract class RoleProvider{ public abstract void CreateRole(string roleName); public abstract bool DeleteRole(string roleName, bool throwOnPopulatedRole); public abstract bool RoleExsts(string roleName); public abstract string[] GetAllRoles(); public abstract void AddUsersToRoles( string[] userNames, string[] roleNames); public abstract void RemoveUsersFromRoles( string[] usernames, string[] roleNames); public abstract string[] GetUsersInRole( string roleName); public abstract string[] FindUsersInRole( string roleName, string usernameToMatch); public abstract string[] GetRolesForUser( string userName); public abstract bool IsUserInRole( string username, string roleName);}
Arkitekturen[PrincipalPermissionAttribute( SecurityAction.Demand, Role="Supervisor")]public void MyMethod(string input){...}
Din kod
Konfiguration
Val av lagring och administration
<system.web> <roleManager enabled="true” defaultProvider="AuthorizationManagerRoleProvider"> <providers> <add name="AuthorizationManagerRoleProvider" type="AuthorizationManagerRoleProvider, Service" description="Role Provider to Authorization Manager" store="msxml://C:\apps\RoleProvider\AuthorizationStore.xml" applicationName="RoleProvider"/> </providers> </roleManager></system.web>
Resurser Webbsidor
http://wcf.netfx3.com Bloggar
http://blogs.msdn.com/craigmcmurtry/
http://pluralsight.com/blogs/dbox/ Böcker och tidskrifter
Programming ”Indigo” MSDN Magazine
http://blogs.msdn.com/[email protected]