WCF + vs2005 Video Note

http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2006/09/13/windows-communication-foundation-videos.aspx

Parameters & Messages

Transfer data via WCF we have 3 ways

            -Parameters (general way)

-Example:

[DataContract]
    public class Employee
    {
        private string m_Name;
        private int m_Age;
        private int m_Salary;
        private string m_Designation;
        private string m_Manager;

        [DataMember]
        public string Name
        {
            get { return m_Name; }
            set { m_Name = value; }
        }

        [DataMember]
        public int Age
        {
            get { return m_Age; }
            set { m_Age = value; }
        }

                        -Need to define [DataContract], [DataMember], and need serialization

            -Typed Message

          

  [MessageContract(Action="..")]
            class AddRequestMessage
            {
                        publicAddRequestMessage(){}
                       
                        [MessageBody(Name="MyBody",Namespace="..")]
                         public AddRequest MyRequest {get;set;}
                       
                        [MessageHeader(Name="MyHeader",Namespace="...")]
                         public int TimeToLive;
            }
           
            [MessageContract(Action="..")]
            classAddResonMEssage
            {
               public AddResonMEssage(){}
              
               [MessageBody]
               public int Result{get;set;}
            }         
           
            [ServiceContract]
            [OpeationContract]
            AddResponseMessageAddTwoNumber(AddRequestMessage a)
           

            -UnTypedMessage : deal with soap message directly

[ServiceContract]
            interfaceIAddTwoNumbers
            {
                        [OpeartionContract]
                        MessageAddTwoNumbers(Message request);
            }         

Binding

            -Predefine the channels

            for example: if we change binding "basicHttpBinding" to "wsHttpBinding" or "netTcpBinding", the transmitted message will be different, "wsHttpBinding" will have some security element

            -Tweak standard binding via bindingConfiguration

                        -security mode

                        -messageencoding

            -Custom bindings

for example: you may not need message encoding, you may not need security etc.

Serialization

   the data want to transfer over network, we need serialization

          -Binaryseraizlabtion via  [Serializable] 

                        -private&public property will be seraizble

                        -you can define "[NonSeriazed]" to omit property to be serialized

                        -if want to custom serilaztion process, you can implement ISerialble

-for example:

[Serializable()]    //Set this attribute to all the classes that want to serialize
    public class Employee : ISerializable //derive your class from ISerializable
    {
        public int EmpId;
        public string EmpName;
        
        //Default constructor
        public Employee()
        {
            EmpId = 0;
            EmpName = null;
        }
        }

public class Person:ISerializable
{
    private string _FirstName;
    private string _LastName;
    public string FirstName
    {
        get { return _FirstName; }
        set { _FirstName = value; }
    }       
    public string LastName
    {
        get { return _LastName; }
        set { _LastName = value; }
    }
    public Person()
    {
    }
    public Person(string FirstName, string LastName)
    {
        this.FirstName = FirstName;
        this.LastName = LastName;
    }
    void ISerializable.GetObjectData(SerializationInfo oInfo, StreamingContext oContext)
    {
        oInfo.AddValue("FirstName", this.FirstName);
        oInfo.AddValue("LastName", this.LastName);
    }
}

            -XMLSerialization via [XmlRoot("MyClass")]

                        -[XmlAttribute("FirstName")]

                        -only serialize public type

                        -if want to custom serilaztion process, implement IXMlSeriazation

-for example:

 [XmlRoot("XmlDocRoot")]
    public class RootClass {
        private int attribute_id;

        [XmlAttribute("id")]
        public int Id {
            get { return attribute_id; }
            set { attribute_id = value; }
        }
    }


public class Animal : IXmlSerializable
{
	public Animal() { }
	public String Name { get; set; }
	public DateTime Birthday { get; set; }

	public System.Xml.Schema.XmlSchema GetSchema() { return null; }

	public void ReadXml(System.Xml.XmlReader reader)
	{
		reader.MoveToContent();
		Name = reader.GetAttribute("Name");
		Boolean isEmptyElement = reader.IsEmptyElement; // (1)
		reader.ReadStartElement();
		if (!isEmptyElement) // (1)
		{
			Birthday = DateTime.ParseExact(reader.
				ReadElementString("Birthday"), "yyyy-MM-dd", null);
			reader.ReadEndElement();
		}
	}

	public void WriteXml(System.Xml.XmlWriter writer)
	{
		writer.WriteAttributeString("Name", Name);
		if (Birthday != DateTime.MinValue)
			writer.WriteElementString("Birthday",
				Birthday.ToString("yyyy-MM-dd"));
	}
}

            -Stand Way via [DataContract]

                        -[DataMember]

 

DataContract Serialization

            - we can define name & namespace

            -if we dont expected client pass less information : Isrequired=true

            -if we allow client pass more information: IExtensibleDataObject

            -if we have dependency between properties: Serialization order : "Order=1"

            -we can add method to execute after serialized

[OnSerialized]

                        -privatevoid AfterSerialized(StreamingContext ctx)

           - we can add method to execute after de-serialized

[OnDeserialized]

                        -privatevoid AfterDeSerailized(StreamingContext ctx)

            -dc.exe tocovert xml schema to data contract class

- for example:

 [DataContract]
    public class Customer : IExtensibleDataObject
    {
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public string Address { get; set; }
        [DataMember]
        public int Salary { get; set; }
        [DataMember]
        public int NewSalary { get; set; }

        public ExtensionDataObject ExtensionData { get; set; }
    }

MessageEncoding

            -Text

            -MTOM


            -Binnary

                        -CustomBinding

                   

<customBinding>
  <binding name="NetHttpBinding">
     <binaryMessageEncoding />
     <httpsTransport />
  </binding>
</customBinding>
     

Message Pattern

            -One way communication:[OperationContract(IsOneWay=true)]

                        -Client not need to wait serive return

            -Duplexcommunication:[ServiceContract(CallbackContract=typeof(IPrntConfirmation)]

                        -Client need to implement "IMyContractCallback", and service will able to callback later

                                    -e.g.:

 Service:


interface IMyContractCallback
{
   [OperationContract] 
   void OnCallback();
}

[ServiceContract(CallbackContract = typeof(IMyContractCallback))] 
interface IMyContract
{
   [OperationContract] 
   void DoSomething();
}

Client

class MyCallback : IMyContractCallback 
{
   public void OnCallback() {...}
}
IMyContractCallback callback = new MyCallback();
InstanceContext context = new InstanceContext(callback);

MyContractClient proxy = new MyContractClient(context);
proxy.DoSomething();

Https Transport  Security

            -Security Features

                        -Authorisation

                        -Auditing

                        -TransferSercurity

                                                -Authentication

                                                -Integrity

                                                -Privacy

Above 3 features is achived by the following two technology:

                                    -TransportSecurity (HTTPS)

                                    -MessageSecurity (WS-Security)

   Steps to use transport Security:

            -1. Certificate

                        -Add certificate to "Trusted Root Certification Authorizor"

                        -Add cerfiticate to Https that listen port 9090:cmd>>httpcfg.exe set ssl -i0.0.0.0:9090 -h XXXX(cert thumbprint)

            -2. endpoint:address set to "https"

            -3. update bindingConfiguration

                        -securitymode="Transport"

                        -OR security mode="TransportWithMessageCredentail"/>

            -How to identify client: Ask user name /password before Client can request go through traffic

                        -option 1: Add<transport clientCredentialsType="Basic"/>:windows basic authentication

                        -option 2: OR<transport clientCredentialsType="Digest"/>

                        -option 3: OR<transport clientCredentialsType="Windows"/>:default get therunning process authentication

                        -option 4: OR<transport clientCredentialsType="Certificate"/>

                        -option 5: OR-<tranport clientCredentailsType="Certificate"/>

                                    + <messageclientCredentailType="UserName"/>           

                        Client Code:

                         -option 1: 

proxy.ClientCredentails.UserNamePassword.UserName=""

                        proxy.ClientCredentails.UserNamePassword.Password=""

                        -option 2: 

                        proxy.ClientCredentails.ImpersonationLevel=TokenImpersonationLevel.Impersonation

                        proxy.ClientCredentails.Digest.ClientCredentail=newNetworkCredentail("username,"password")

                        -option 3: 

                        proxy.ClientCredentails.Windows.ClientCredentail=newNetworkCredentail("username,"password")

                        -option 4: 

                        -add client certificate to server machine "trusted Root CertificationAuthorities"

                        -Clientside

                                    -behaviorConfiguration

                                                -<clientCredentials>

                                                            <clientCertificatestore Name="My" storeLocation="CurrentUser"x509FindType="xx"

                                                                        findValue="xxx"/>

                          -option 5:                                               

                        proxy.ClientCredentails.UserNamePassword.UserName=""

                        proxy.ClientCredentails.UserNamePassword.Password=""

+option 4                       

Message Security

            -TransportLevel Security: Transport Security

            -SOAP LevelSecurity: Message Security use (WS-Security features), inside SOAP Message

            -except basicHttpBinding, other binding by default, send security information toservice, by default is windows security information

            -<security mode="Message">

                        -option1 : <message clientCredentialType="Windows">

                        -option2: <message clientCredentialType="UserName">

                            +servicebehavior - to encode username to transfer via network

                                                -<serviceCredetntails>

                                                            -<serviceCertificatex509FindType="" storeLocation="" storeName="

                                                                        findValue=""

                                                                       

                        -option3: <message clientCredentailType="Certificate">

                                    +servicebehavior

                                                -<clientCredentails>

                                                           

                       

            -Client Code

-option1 : 

                        proxy.ClientCredentails.Windows.ClientCredentail=newNetworkCredentail("username,"password")

                       -option2 : 

                        proxy.ClientCredentails.UserNamePassword.UserName=""

                        proxy.ClientCredentails.UserNamePassword.Password=""

                        +clientbehavior: to encode the username and password

                                    -<clientCredentials>

                                                -<serviceCertificate x509FindType="" storeLocation="" storeName="

                                                                        findValue=""

                       -option3 :                                                 

                        <clientCredentials>

                                    <clientCertificatestore Location="CurrentUser" StoreName=""...

                                                                       

            -Custom "UserName" provider: not really need to link to windows account. we can create custom .net membership provider

                        +<servicebehavior>

                                                -<serviceCredetntails>

                                                            -<serviceCertificatex509FindType="" storeLocation="" storeName="

                                                                        findValue=""

                                                            <userNamePasswordmembershipProviderName="MyProvider"/>

                                                           

            -"defaultProtectionLevel"

                        <messageclientCredentialType=""

                        negotiateServiceCredentail="false"

                        defaultProtectionLevel="EncryptAndSign"/>

                       

Concurrency

            -ConcurrencyMode=ConcurrencyMode.Single

                                                            ConcurrencyMode.Multiple

                                                            ConcurrencyMode.Reentrant

                                                           

Instancing

            -InstanceContextMode=InstanceContextMode.PerCall

                                                                        InstanceContextMode.PerSession

                                                                        InstanceContextMode.Single

                                                                       

Sessions

[ServiceContract(SessionMode=SessionMode.Required)]

Client:string sessionId=OperationContext.Current.SessionIdentifier;

           

            -[OperationContract(IsInitiating=true)]

            -[OperationContract(IsInitiating=false)]

            -[OperationContract(IsTerminating=true)]

 

Transaction

            -if transaction cross process need a distribute transaction

            -[OperationContract]

            -[TransactionFlow(TransactionFlowOption.Allowed)]

                        +bindingConfiguration

                                    <bindingtransactionFlow="true" transactionProtocal="oleTx"/>

            -[TransactionFlow(TransactionFlowOption.NotAllowed)]

            -[TransactionFlow(TransactionFlowOption.Required)]

           

            [OpeartionBehavior(TransactionScopeRequired=true)]

            using(TransactionScopescope =new TransactionScope(){

                        //ifalready has transaction then use it

                        //ifthere is no transaction then add new

            }

            Client Code:

            using(TransactionScopescope=new TransactionScope()){

                        //Dosomething,proxy.aaa

                       

                        //Dosomething,proxy.bbb

            }

 

Exception

            -why by default not send exception type and eception message, and not stack trace

                        -clientside may not understand .net exception

                        -forsome security risk

            -[ServiceBehavior(includeExceptionDetailInFaults=true)]

                        -getting exception message, stack trace but not exception type

           

            -[ServiceContract]

             [FaultContract(typeof(InvalidOperationException))]

                        -getting exception type + exception message and stack trace

throw newFaultException<InvalidOperationException>(newInvalidOperationException(".."));

            -Need custom process can implement :IErrorHandler

           

Authorisation

           -option 1 

 -[OpeationContract]

            -[PrincipalPermission(SecurityAction.Demand,Role="General User")]

           

            -Not necessary to use windows group , we can use asp.net role management

                        -serviceBehavior

                                    <serviceAuthoriaztionprincipalPermissionMode="UseAspNetRole"/>

            -option 2                        

            -Dynamicallyget current user role and make decisions

            serviceSecurityContextctx=ServiceSecurityContext.Current;

           

            -option 3

implement class CustomOperationRequirement: OperationRequirement

                        +<serviceAuthoriaztionprincipalPermissionMode="UseAspNetRole"opeationRequirementType="CustomOpeartionRequirement/>

                       

Audit

            -ServiceBehavior

                        -<serviceSecurityAudit

                                    auditLogLocation="Application"

                                    messageAuthenticationAuditLevel="SuccesOrFailure"

                                    serviceAuthorizationAuditLevel="SuccesOrFailure"/>

             

    

           

           

           

           

           

           

           

                       

                       

                       

           

                       

                       

                       

                       

                       

                       

                       

           

                        

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章