zoukankan      html  css  js  c++  java
  • WCF服务编程读书笔记(1,2):WCF基础 & 服务契约

    例2-1:服务端的操作重载

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    
    namespace WCFServiceProgramming
    {
        [ServiceContract]
        class ICalculator
        {
            [OperationContract(Name = "AddInt")]
            int Add(int arg1, int arg2);
    
            [OperationContract(Name = "AddDouble")]
            double Add(double arg1, double arg2);
        }
    }
    View Code

    例2-2:客户端操作重载

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    
    namespace WCFServiceProgramming
    {
        public partial class CalculatorClient : ClientBase<ICalculator>, ICalculator
        {
            public int Add(int arg1, int arg2)
            {
                return Channel.Add(arg1, arg2);
            }
    
            public double Add(double arg1, double arg2)
            {
                return Channel.Add(arg1, arg2);
            }
        }
    }
    View Code

    例 2-3:服务端契约层级

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    
    namespace WCFServiceProgramming
    {
        [ServiceContract]
        interface ISimpleCalculator
        {
            [OperationContract]
            int Add(int arg1, int arg2);
        }
    
        [ServiceContract]
        interface IScientificCalculator : ISimpleCalculator
        {
            [OperationContract]
            int Multiply(int arg1, int arg2);
        }
    
        class MyCalculator : IScientificCalculator
        {
            public int Multiply(int arg1, int arg2)
            {
                return arg1 * arg2;
            }
    
            public int Add(int arg1, int arg2)
            {
                return arg1 + arg2;
            }
        }
    }
    View Code

    例2-4:取消层级关系的客户端定义

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    
    namespace WCFServiceProgramming
    {
        [ServiceContract]
        public interface IScientificCalculator 
        {
            [OperationContract(Action=".../ISimpleCalculator/Add", 
                ReplyAction=".../ISimpleCalculator/AddResponse")]
            int Add(int arg1, int arg2);
    
            [OperationContract(Action=".../IScientificCalculator/Multiply", 
                ReplyAction=".../IScientificCalculator/MultiplyResponse")]
            int Multiply(int arg1, int arg2);
        }
    
        public partial class ScientificCalculatorClient : 
            ClientBase<IScientificCalculator>, IScientificCalculator
        {
            public int Add(int arg1, int arg2)
            {
                return arg1 + arg2;
            }
    
            public int Multiply(int arg1, int arg2)
            {
                return arg1 * arg2;
            }
        }
    }
    View Code

    例2-5:客户端契约层级

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    
    namespace WCFServiceProgramming
    {
        [ServiceContract]
        public interface ISimpleCalculator
        {
            [OperationContract]
            int Add(int arg1, int arg2);
        }
    
        public partial class SimpleCalculatorClient : 
            ClientBase<ISimpleCalculator>, ISimpleCalculator
        {
            public int Add(int arg1, int arg2)
            {
                return Channel.Add(arg1, arg2);
            }
        }
    
        [ServiceContract]
        public interface IScientificCalculator : ISimpleCalculator
        {
            [OperationContract]
            int Multiply(int arg1, int arg2);
        }
    
        public partial class ScientificCalculatorClient : 
            ClientBase<IScientificCalculator>, IScientificCalculator
        {
            public int Add(int arg1, int arg2)
            {
                return Channel.Add(arg1, arg2);
            }
    
            public int Multiply(int arg1, int arg2)
            {
                return Channel.Multiply(arg1, arg2);
            }
        }
    }
    View Code

    例2-6:代理链

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    
    namespace WCFServiceProgramming
    {
        [ServiceContract]
        public interface ISimpleCalculator
        {
            [OperationContract]
            int Add(int arg1, int arg2);
        }
    
        [ServiceContract]
        public interface IScientificCalculator : ISimpleCalculator
        {
            [OperationContract]
            int Multiply(int arg1, int arg2);
        }
    
        public partial class SimpleCalculatorClient :
            ClientBase<IScientificCalculator>, ISimpleCalculator
        {
            public int Add(int arg1, int arg2)
            {
                return Channel.Add(arg1, arg2);
            }
        }
    
        public partial class ScientificCalculatorClient : 
            SimpleCalculatorClient, IScientificCalculator
        {
            public int Multiply(int arg1, int arg2)
            {
                return Channel.Multiply(arg1, arg2);
            }
        }
    }
    View Code

    例2-7:支持元数据处理的类型

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Runtime;
    using System.Xml;
    using System.Xml.Serialization;
    using System.Net;
    using System.Net.Mime;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.Text;
    
    namespace System.ServiceModel.Description
    {
        public enum MetadataExchangeClientMode
        {
            MetadataExchange = 0,
            HttpGet = 1,
        }
    
        public class MetadataSet : IXmlSerializable
        {
        }
    
        public class ServiceEndpointCollection : Collection<ServiceEndpoint>
        {
        }
    
        public class MetadataExchangeClient
        {
            public MetadataExchangeClient();
            public MetadataExchangeClient(Binding mexBinding);
            public MetadataExchangeClient(Uri address, MetadataExchangeClientMode mode);
    
            public MetadataSet GetMetadata();
            public MetadataSet GetMetadata(EndpointAddress address);
        }
    
        public abstract class MetadataImporter
        {
            public abstract ServiceEndpointCollection ImportAllEndpoints();
        }
    
        public class WsdlImporter : MetadataImporter
        {
            public WsdlImporter(MetadataSet metadata);
        }
    
        public class ServiceEndpoint
        {
            public EndpointAddress Address { get; set; }
            public Binding Binding { get; set; }
            public ContractDescription Contract { get; set; }
        }
    
        public class ContractDescription
        {
            public string Name { get; set; }
            public string Namespace { get; set; }
        }
    }
    View Code

    例2-8:查询契约的地址

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Description;
    
    namespace WCFServiceProgramming
    {
        class Program
        {
            static void Main(string[] args)
            {
                bool contractSupported = false;
                string mexAddress = "...?WSDL";
    
                MetadataExchangeClient mexClient = new MetadataExchangeClient(
                    new Uri(mexAddress), MetadataExchangeClientMode.HttpGet);
    
                MetadataSet metadata = mexClient.GetMetadata();
                MetadataImporter importer = new WsdlImporter(metadata);
    
                ServiceEndpointCollection endpoints = importer.ImportAllEndpoints();
    
                foreach (ServiceEndpoint endpoint in endpoints)
                {
                    if (endpoint.Contract.Namespace == "MyNamespace" && 
                        endpoint.Contract.Name == "IMyContract")
                    {
                        contractSupported = true;
                        break;
                    }
                }
            }
        }
    }
    View Code

    例 2-9 MetadataHelper.QueryContract() 的实现

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel.Description;
    using System.ServiceModel.Channels;
    using System.ServiceModel;
    using System.Diagnostics;
    
    namespace WCFServiceProgramming
    {
        public static class MetadataHelper
        {
            const int MessageMultiplier = 5;
    
            static ServiceEndpointCollection QueryMexEndpoint(string mexAddress, 
                BindingElement bindingElement)
            {
                CustomBinding binding = new CustomBinding(bindingElement);
    
                MetadataExchangeClient MEXClient = new MetadataExchangeClient(binding);
                MetadataSet metadata = MEXClient.GetMetadata(new EndpointAddress(mexAddress));
    
                MetadataImporter importer = new WsdlImporter(metadata);
                return importer.ImportAllEndpoints();
            }
    
            public static ServiceEndpoint[] GetEndpoints(string mexAddress)
            {
                Uri address = new Uri(mexAddress);
                ServiceEndpointCollection endpoints = null;
    
                if(address.Scheme == "net.tcp")
                {
                    TcpTransportBindingElement tcpBindingElement = new TcpTransportBindingElement();
    
                    tcpBindingElement.MaxReceivedMessageSize *= MessageMultiplier;
                    endpoints = QueryMexEndpoint(mexAddress,tcpBindingElement);
                }
    
                if (address.Scheme == "net.pipe") { }
                if (address.Scheme == "http") { }
                if (address.Scheme == "https") { }
    
                return endpoints.ToArray();
            }
    
            public static bool QueryContract(string mexAddress, Type contractType)
            {
                if (contractType.IsInterface == false)
                {
                    Debug.Assert(false, contractType + " is not an interface");
                    return false;
                }
    
                object[] attributes = contractType.GetCustomAttributes(
                    typeof(ServiceContractAttribute), false);
    
                if (attributes.Length == 0)
                {
                    Debug.Assert(false, "Interface " + contractType + " does not have the ServiceContractAttribute");
                    return false;
                }
    
                ServiceContractAttribute attribute = attributes[0] as ServiceContractAttribute;
    
                if (attribute.Name == null)
                {
                    attribute.Name = contractType.ToString();
                }
    
                if (attribute.Namespace == null)
                {
                    attribute.Namespace = "http://tempuri.org/";
                }
    
                return QueryContract(mexAddress, attribute.Namespace, attribute.Name);
            }
    
            private static bool QueryContract(string mexAddress, string contractNamespace, string contractName)
            {
                if (String.IsNullOrEmpty(contractNamespace))
                {
                    Debug.Assert(false, "Empty namespace");
                    return false;
                }
    
                if (String.IsNullOrEmpty(contractName))
                {
                    Debug.Assert(false, "Empty name");
                    return false;
                }
    
                try
                {
                    ServiceEndpoint[] endpoints = GetEndpoints(mexAddress);
    
                    foreach (ServiceEndpoint endpoint in endpoints)
                    {
                        if (endpoint.Contract.Namespace == contractNamespace
                            && endpoint.Contract.Name == contractName)
                        {
                            return true;
                        }
                    }
                }
                catch { }
    
                return false;
            }
        }
    }
    View Code

    例 2-10 MetadataHelper类

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel.Description;
    using System.ServiceModel.Channels;
    using System.ServiceModel;
    using System.Diagnostics;
    
    namespace WCFServiceProgramming
    {
        public static class MetadataHelper
        {
            public static ServiceEndpoint[] GetEndpoints(string mexAddress);
    
            public static string[] GetAddresses(string mexAddress, Type contractType);
            public static string[] GetAddresses(string mexAddress, string contractNamespace, string contractName);
            public static string[] GetAddresses(Type bindingType, string mexAddress, Type contractType);
            public static string[] GetAddresses(Type bindingType, 
                string mexAddress, string contractNamespace, string contractName);
    
            public static string[] GetContracts(string mexAddress);
            public static string[] GetContracts(Type bindingType, string mexAddress);
    
            public static string[] GetOperations(string mexAddress, Type contractType);
            public static string[] GetOperations(string mexAddress, string contractNamespace, string contractName);
    
            public static bool QueryContract(string mexAddress, Type contractType);
            public static bool QueryContract(string mexAddress, string contractNamespace, string contractName);
        }
    }
    View Code
  • 相关阅读:
    非常适合新手的一个Python爬虫项目: 打造一个英文词汇量测试脚本!
    代码遇到异常怎么办?不要慌,来看看这个!
    老司机要开车了!用Selenium+PhantomJS来抓取煎蛋网妹子图
    Python基础之格式化输出函数format()功能详解
    Python基础之常用格式化输出字符详解
    新手学python,如何才能更快升职加薪,迎娶白富美,走上人生巅峰
    ASP.NET MVC学习笔记 第二天
    ASP.NET MVC学习笔记 第一天
    ActiveMQ相关:
    WPF中使用定时器 DispatcherTimer 做TCP连接中的心跳 HeartBeat
  • 原文地址:https://www.cnblogs.com/thlzhf/p/2783011.html
Copyright © 2011-2022 走看看