2

The question is related to an existing discussion: Get Client IP address using WCF 4.5 RemoteEndpointMessageProperty in load balancing situation

RemoteEndpointMessageProperty is not supported in .NET standard 2.0. Does anyone know if there is an alternative way to retrieve the client IP address off a OperationContext::IncomingMessageProperties.

Basil Kosovan
  • 888
  • 1
  • 7
  • 30
mmiao
  • 21
  • 3
  • Have you achieved any results? – Basil Kosovan Oct 18 '19 at 13:00
  • There's nothing "standard" about WCF. .NETCore is how they want to move ahead, there are several .NET features they do not want to maintain. Server-side WCF is on that list. You're completely stuck with targeting .NETFramework if you don't want move to an alternative technology stack. – Hans Passant Oct 18 '19 at 23:10

1 Answers1

1

You can copy/paste the class from the 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
        }
    }
}
Kahbazi
  • 14,331
  • 3
  • 45
  • 76
  • I want to use this package in .net core and .net framework project. If I copy a class I will have class conflicts. – Basil Kosovan Oct 19 '19 at 11:08
  • You can rename the class if you want, but the functionality works for both NET Core and .NET framework – Kahbazi Oct 19 '19 at 11:15
  • The existing .netfraemwork project already has an instance of RemoteEndpointMessageProperty. I don't like the idea to map these objects – Basil Kosovan Oct 19 '19 at 11:17
  • Well this is the `alternative way to retrieve the client IP address off a OperationContext::IncomingMessageProperties`! – Kahbazi Oct 19 '19 at 11:20