Välkommen till Sommarkollo 2006 Windows Communication Foudnation

Post on 12-Mar-2016

40 views 5 download

Tags:

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

Transcript of Välkommen till Sommarkollo 2006 Windows Communication Foudnation

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/johanljohan.lindfors@microsoft.com