wCF REST 注意点

服务注册路径问题

RouteTable.Routes.Add(new ServiceRoute("Ipc/", hostFactory, typeof(ServiceImp)));
RouteTable.Routes.Add(new ServiceRoute("Ipc/LoginService/", hostFactory, typeof(LoginServiceImp)));
这样注册的顺序会导致Ipc/LoginService/xxx 发布的终结点找不到,把后一句的移到前面,又正常了

RouteTable.Routes.Add(new ServiceRoute("Ipc/", hostFactory, typeof(ServiceImp)));
RouteTable.Routes.Add(new ServiceRoute("Ipc2/LoginService/", hostFactory, typeof(LoginServiceImp)));

路径前缀不同的也可以正常访问到

使用WebInvoke时只支持一个参数

默认的web方式实例管理是采用PerCall的,这样服务类针对每次调用都会New一次

View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Concurrent;
using System.Diagnostics;
namespace DynamicIP.Server.IIS
{
    using DynamicIP.Interface;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Activation;
    using System.Web;


    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
    [ServiceBehavior(IncludeExceptionDetailInFaults = true,InstanceContextMode = InstanceContextMode.PerCall)]
    public  partial class ServiceImp : IService
    {
        public ServiceImp()
        {
            Debug.WriteLine(this.GetHashCode());
        }
        #region IDynamicIpService 成员

        public string  RegIp(string clientNo)
        {
            var properties = OperationContext.Current.IncomingMessageProperties;
          
            var endPoint = properties[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;
            var ip= endPoint.Address;
            var model = new ClientIpModel()
            {
                AddTime = DateTime.Now,
                ClientNo = clientNo,
                IP = ip,
                RecId = -1,
                UpdateTime = DateTime.Now
            };
            ClientIpDB.Instance.Save(model);
            
            Console.WriteLine(string.Format("ClientNo:{0},IP:{1}",clientNo,ip));
           
           

            return DateTime.Now + "-->" + ip;


        }

        public List<ClientIpModel>  Query(string clientNo, int top, string inbTime, string ineTime)
        {
            DateTime bt, et;
            DateTime? bTime = null, eTime = null;

            if (DateTime.TryParse(inbTime, out bt))
            {
                bTime = bt;
            }
            if (DateTime.TryParse(ineTime, out et))
            {
                eTime = et;
            }
            if (top <= 0) top = 100;

            return ClientIpDB.Instance.Query(clientNo, top, bTime, eTime);
        }

        public string Help()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("格式:/Query?clientNo={clientNo}&top={top}&btime={btime}&etime={etime}");

            return sb.ToString();
        }

        #endregion



        #region IService 成员


        public int Add(int a, int b)
        {
            return a + b;
        }

        #endregion
    }
    #region 客户域名库
    public class ClientIpDB
    {
        private ClientIpDB(){}
        private static Lazy<ClientIpDB> _LazyClientIpDB = new Lazy<ClientIpDB>(() => new ClientIpDB(), true);
        public static ClientIpDB Instance
        {
            get
            {
                return _LazyClientIpDB.Value;
            }

        }
       

        private static volatile int MaxRecId=0;

        public int GetMaxId()
        {
            return ++MaxRecId;
        }
        private static int MaxElmCount = 11000;
        private static int MoveCount = 1000;
        private ConcurrentQueue<ClientIpModel> _Queue = new ConcurrentQueue<ClientIpModel>();

        /// <summary>
        /// 获取对应客户号的域名
        /// </summary>
        /// <param name="clientId"></param>
        /// <returns></returns>
        public string GetDomainBy(string clientNo)
        {
            return "www.geely.com";
        }

        public void Save(ClientIpModel model)
        {
            var it= Update(model);
            if (it == null)
            {
                model.RecId = GetMaxId();
                Add(model);
            }
        }
        public ClientIpModel Update(ClientIpModel model)
        {
            var it= _Queue.Where(ent => ent.ClientNo == model.ClientNo).FirstOrDefault();
            if (it != null)
            {
                it.IP = model.IP;
                it.UpdateTime = DateTime.Now;
                it.Domain = model.Domain;
                    
            }
            return it;
        }
        public void Add(ClientIpModel model)
        {
            _Queue.Enqueue(model);

            if (_Queue.Count > MaxElmCount  )
            {
                for (int i = 0; i < MoveCount; i++)
                {
                    ClientIpModel outIt=null;
                    _Queue.TryDequeue(out outIt);
                }
            }
        }

        public List<ClientIpModel> Query(string clientNo,int top, DateTime? btime, DateTime? etime)
        {
            var q=_Queue.AsQueryable();
            if(!string.IsNullOrWhiteSpace(clientNo))
            {
                q = q.Where(ent => ent.ClientNo == clientNo);
            }
            if (btime.HasValue)
            {
                q = q.Where(ent => ent.UpdateTime >= btime);

            }
            if (etime.HasValue)
            {
                q = q.Where(ent => ent.UpdateTime <= etime);

            }
            return q.Take(top).ToList();

            
        }


    }
   #endregion
}

客户端调用时需要指定个定WebHttpBehavior

View Code
//#define Release

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DynamicIP.Console
{
    using DynamicIP.Interface;
    using System.ServiceModel;
    using System.Runtime.InteropServices;
    using System.ServiceModel.Description;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Dispatcher;
    using System.Web;
    public class MyClientMsgInspector : IClientMessageInspector, IEndpointBehavior
    {

        #region IClientMessageInspector 成员
        private string _AuthUserId = string.Empty;

        public void AfterReceiveReply(ref Message reply, object correlationState)
        {
            if (reply.Properties.ContainsKey("httpResponse"))
            {
                HttpResponseMessageProperty httpResponse = reply.Properties["httpResponse"] as HttpResponseMessageProperty;

                if (httpResponse != null)
                {
                    
                    string cookie = httpResponse.Headers.Get("Set-Cookie");
                    if (!string.IsNullOrWhiteSpace(cookie))
                    {
                        _AuthUserId = cookie;
                    }
                    //if (cookie != null) _cookie = cookie;
                }
            }

        }

        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        {
            if (_AuthUserId != string.Empty && request.Properties.ContainsKey("httpRequest"))
            {
                HttpRequestMessageProperty httpRequest = request.Properties["httpRequest"] as HttpRequestMessageProperty;

                if (httpRequest != null)
                {
                    httpRequest.Headers["Cookie"] = _AuthUserId;
                  
                }
            }

            return null;


        }

        #endregion

        #region IEndpointBehavior 成员

        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
            return;
        }
        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            clientRuntime.MessageInspectors.Add(this);
        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
            return;
        }

        public void Validate(ServiceEndpoint endpoint)
        {
            return;
        }

        #endregion
    }
    class Program
    {

        #region 平台调用 & console 窗口隐藏
        [DllImport("user32.dll")]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll")]
        static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

        public static void SetConsoleWindowVisibility(bool visible, string title)      
        {            
            // below is Brandon's code           
            //Sometimes System.Windows.Forms.Application.ExecutablePath works for the caption depending on the system you are running under.          
            IntPtr hWnd = FindWindow(null, title);
        
            if (hWnd != IntPtr.Zero)           
            {              
                if (!visible)                  
                    //Hide the window                   
                    ShowWindow(hWnd, 0); // 0 = SW_HIDE               
                else                  
                     //Show window again                   
                    ShowWindow(hWnd, 1); //1 = SW_SHOWNORMA          
             }       
        }
  

        #endregion
        [STAThread()]
        static void Main(string[] args)
        {
#if Release
            var title = Guid.NewGuid().ToString("N");
            Console.Title = title;
            SetConsoleWindowVisibility(false, title);
#endif
            //try
            //{
                 var binding = new WebHttpBinding();
                 binding.AllowCookies = true;
                   
                 var clientMsgInspector = new MyClientMsgInspector();

                 var address1 = new EndpointAddress("http://localhost:13773/Ipc/loginService/");
                 var sep1 = new ServiceEndpoint(ContractDescription.GetContract(typeof(ILogin)), binding, address1);
                 sep1.Behaviors.Add(new WebHttpBehavior());

                 using (ChannelFactory<ILogin> channelFactory = new ChannelFactory<ILogin>(sep1))
                 {
                     channelFactory.Endpoint.Behaviors.Add(clientMsgInspector);

                     var proxy = channelFactory.CreateChannel();
                     var clientNo = System.Configuration.ConfigurationManager.AppSettings["ClientNo"];
                     proxy.Login(new LoginRequest() { Username = "xx", Password = "xx" });

                     
                 }
                 System.Console.ReadKey();

                 var address = new EndpointAddress("http://localhost:13773/Ipc/ipService");
                 var sep = new ServiceEndpoint(ContractDescription.GetContract(typeof(IService)), binding, address);
                 sep.Behaviors.Add(new WebHttpBehavior());
                using (ChannelFactory<IService> channelFactory = new ChannelFactory<IService>(sep))
                {
                    channelFactory.Endpoint.Behaviors.Add(clientMsgInspector);
                    var proxy = channelFactory.CreateChannel();

                   //var scope = new OperationContextScope(((IClientChannel)proxy));
                   //var curId = Guid.NewGuid();
                   // MessageHeader<Guid> mhg = new MessageHeader<Guid>(curId);
                   // MessageHeader untyped = mhg.GetUntypedHeader("token", "ns");
                   // OperationContext.Current.OutgoingMessageHeaders.Add(untyped);


                    var clientNo = System.Configuration.ConfigurationManager.AppSettings["ClientNo"];
                    proxy.RegIp(clientNo);

                    var t= proxy.Query("", 100, "", "");


                    var proxy2 = channelFactory.CreateChannel();
                    clientNo = System.Configuration.ConfigurationManager.AppSettings["ClientNo"];
                    proxy2.RegIp("9999");

                    var t2 = proxy2.Add(5, 16);
                }
                


            //}
            //catch (Exception)
            //{
            //    //eat err
            //}

            System.Console.ReadKey();
        }
    }
}

cookie问题
var binding = new WebHttpBinding();
binding.AllowCookies = true; 设置的cookie http头不能正确提交
 而当allowCookies=false,客户端可以提交cookie http头

原文地址:https://www.cnblogs.com/wdfrog/p/3026542.html