330 likes | 495 Views
Top 10 Tricks & Tips for WCF. Barry Dorrans http://idunno.org. About the Speaker (the ego slide). MVP – Visual Tools, Security barryd@idunno.org. Agenda 1) The test harnesses 2) Don’t use Using 3) It’s all your fault 4) Migrating an ASMX 5) Message Inspectors 6) Custom Authentication
E N D
Top 10 Tricks & Tips for WCF Barry Dorrans http://idunno.org
About the Speaker(the ego slide) MVP – Visual Tools, Security barryd@idunno.org
Agenda 1) The test harnesses 2) Don’t use Using 3) It’s all your fault 4) Migrating an ASMX 5) Message Inspectors 6) Custom Authentication 7) Port sharing 8) Callbacks 9) Logging 10) RESTful services
What is WCF? Indigo Replaces Web Services, WSE & Remoting Interoperability
The ABCs of WCF Address Binding Contract
Client Server Messaging Layer Endpoint Service Model Address Binding Channel Behaviour Behaviour Contract Binding Binding Channel Behaviour Behaviour Factory Listener Channel Address Address Channel *
Address scheme:// <machineName>[:port]/path http://localhost:8080/Account/ net.tcp://localhost:8080/Account
Binding How you communicate with a service A service may have multiple bindings Defines the shape; security etc.
Contract The external interface Contracts for service, data and message
The ABCs Address = WHERE Binding = HOW Contract = WHAT
Service Contracts [ServiceContract()] public interface IMyService { [OperationContract] string MyOperation1(string myValue); [OperationContract] string MyOperation2(MyDataContract value); }
Data Contracts [DataContract] public class MyDataContract { string _stuff; [DataMember] public string Stuff { get { return _stuff; } set { stuff = value; } } }
Disposing the right way Service1Client proxy = null; try { proxy = new Service1Client(....); } catch (...) finally { if (proxy != null) { try { if (proxy.State == CommunicationState.Opened) proxy.Close(); else if (proxy.State == CommunicationState.Faulted) proxy.Abort(); } catch (CommunicationException) { proxy.Abort(); } catch (TimeoutException) { proxy.Abort(); } } }
Faults the right way In Contract Code [ServiceContract] public interface IService1 { [OperationContract] [FaultContract(typeof(NegativeNumberFault))] string GetDataWithFault(int value); } [DataContract] public class NegativeNumberFault { } In Service Code throw new FaultException<NegativeNumberFault>( new NegativeNumberFault(), new FaultReason("value was negative")); In Client Code try { .... } catch (FaultException<NegativeNumberFault>) { .... }
Migrating an ASMX Change the protocol binding to basicHttpBinding Match your namespaces [ServiceContract(Namespace="http:/tempuri.org/")] Match your actions[OperationContract(Action = "http://tempuri.org/HelloWorld")] Match your message names (if you use them)[OperationContract(Action = "http://tempuri.org/HelloWorld", Name = "MyMessageName")] Change the serializer to use XmlSerializer[XmlSerializerAttribute] public class MyService
Migrating an ASMX Make WCF answer ASMX<buildProviders> <remove extension=".asmx"/> <add extension=".asmx"type="System.ServiceModel.Activation.ServiceBuildProvider, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/> </buildProviders>
Message Inspectors Can be client or server side Messages can be modified – but you must copy the message then replace it. Apply the custom behaviour via config or via an attribute.
Custom Authentication Reference System.IdentityModel andSystem.IdentityModel.Selectors Implement a UsernamePasswordValidator Plug it in via config
Port Sharing Vista / Windows 2008 – netsh http add urlaclurl=http://+:port/url/ user=\Everyone XP / Windows 2003 (Support Tools)–httpcfg set urlacl /uhttp://*:80/url//a D:(A;;GX;;;NS) XP does not port share with IIS.
Callbacks Publish / Subscribe model works best Declare a callback interfaceinterface IMessageCallback { [OperationContract(IsOneWay = true)] void OnMessageAdded(string message, DateTime timestamp); } Add the callback to the service contract.[ServiceContract(CallbackContract = typeof(IMessageCallback))] Implement callback interface on client.
RESTful services Reference System.ServiceModel.Web Use WebHttpBinding and WebHttpBehavior Decorate contract with WebGet or WebInvoke[OperationContract][WebInvoke(Method = "POST", UriTemplate = "")]void AddMessage(Message message);[OperationContract][WebInvoke(Method = "DELETE", UriTemplate = "{id}")]void DeleteMessage(string id);[OperationContract][WebGet(UriTemplate = "{id}")]Message GetMessage(string id);[OperationContract][WebGet(UriTemplate = "")]List<Message> GetMessages();
RESTful services Avoid the hassle and use the REST starter kithttp://msdn.microsoft.com/en-us/netframework/wcf/rest