在.NET标准中替换RemoteEndpointMessageProperty以获取客户端IP地址

时间:2019-03-05 01:14:13

标签: .net-core

该问题与现有讨论有关:Get Client IP address using WCF 4.5 RemoteEndpointMessageProperty in load balancing situation

.NET标准2.0不支持RemoteEndpointMessageProperty。有谁知道是否有另一种方法可以从OperationContext :: IncomingMessageProperties检索客户端IP地址。

1 个答案:

答案 0 :(得分:1)

您可以从source code

复制/粘贴课程
namespace System.ServiceModel.Channels
{
    using System;
    using global::System.Net;

    public sealed class RemoteEndpointMessageProperty
    {
        string address;
        int port;
        IPEndPoint remoteEndPoint;
        IRemoteEndpointProvider remoteEndpointProvider;
        InitializationState state;
        object thisLock = new object();

        public RemoteEndpointMessageProperty(string address, int port)
        {
            if (string.IsNullOrEmpty(address))
            {
                throw new ArgumentNullException(nameof(address));
            }

            if (port < IPEndPoint.MinPort || port > IPEndPoint.MaxPort)
            {
                throw new ArgumentOutOfRangeException(nameof(port));
            }

            this.port = port;
            this.address = address;
            this.state = InitializationState.All;
        }

        internal RemoteEndpointMessageProperty(IRemoteEndpointProvider remoteEndpointProvider)
        {
            this.remoteEndpointProvider = remoteEndpointProvider;
        }

        internal RemoteEndpointMessageProperty(IPEndPoint remoteEndPoint)
        {
            this.remoteEndPoint = remoteEndPoint;
        }

        public static string Name
        {
            get { return "System.ServiceModel.Channels.RemoteEndpointMessageProperty"; }
        }

        public string Address
        {
            get
            {
                if ((this.state & InitializationState.Address) != InitializationState.Address)
                {
                    lock (ThisLock)
                    {
                        if ((this.state & InitializationState.Address) != InitializationState.Address)
                        {
                            Initialize(false);
                        }
                    }
                }
                return this.address;
            }
        }

        public int Port
        {
            get
            {
                if ((this.state & InitializationState.Port) != InitializationState.Port)
                {
                    lock (ThisLock)
                    {
                        if ((this.state & InitializationState.Port) != InitializationState.Port)
                        {
                            Initialize(true);
                        }
                    }
                }
                return this.port;
            }
        }

        object ThisLock
        {
            get { return thisLock; }
        }

        void Initialize(bool getHostedPort)
        {
            if (remoteEndPoint != null)
            {
                this.address = remoteEndPoint.Address.ToString();
                this.port = remoteEndPoint.Port;
                this.state = InitializationState.All;
                this.remoteEndPoint = null;
            }
            else
            {
                if ((this.state & InitializationState.Address) != InitializationState.Address)
                {
                    this.address = remoteEndpointProvider.GetAddress();
                    this.state |= InitializationState.Address;
                }

                if (getHostedPort)
                {
                    this.port = remoteEndpointProvider.GetPort();
                    this.state |= InitializationState.Port;
                    this.remoteEndpointProvider = null;
                }
            }
        }

        internal interface IRemoteEndpointProvider
        {
            string GetAddress();
            int GetPort();
        }

        [Flags]
        enum InitializationState
        {
            None = 0,
            Address = 1,
            Port = 2,
            All = 3
        }
    }
}