দূরবর্তী হোস্টের আইপি ঠিকানা পান


136

এএসপি.নেটে একটি System.Web.HttpRequestশ্রেণি রয়েছে, যার মধ্যে এমন ServerVariablesসম্পত্তি রয়েছে যা আমাদের REMOTE_ADDRসম্পত্তি মূল্য থেকে আইপি ঠিকানা সরবরাহ করতে পারে।

তবে, আমি এএসপি.নেট ওয়েব এপিআই থেকে দূরবর্তী হোস্টের আইপি ঠিকানা পাওয়ার অনুরূপ কোনও উপায় খুঁজে পাইনি।

অনুরোধ করা দূরবর্তী হোস্টের আইপি ঠিকানা আমি কীভাবে পেতে পারি?

উত্তর:


189

এটি করা সম্ভব, তবে খুব আবিষ্কারযোগ্য নয় - আপনাকে আগত অনুরোধ থেকে সম্পত্তি ব্যাগটি ব্যবহার করতে হবে এবং আপনি যে সম্পত্তিটি অ্যাক্সেস করতে হবে তা নির্ভর করে আপনি আইআইএস (ওয়েবহোস্টেড) এর অধীনে ওয়েব এপিআই ব্যবহার করছেন কিনা বা স্ব-হোস্টেড তার উপর নির্ভর করে। নীচের কোডটি দেখায় যে এটি কীভাবে করা যায়।

private string GetClientIp(HttpRequestMessage request)
{
    if (request.Properties.ContainsKey("MS_HttpContext"))
    {
        return ((HttpContextWrapper)request.Properties["MS_HttpContext"]).Request.UserHostAddress;
    }

    if (request.Properties.ContainsKey(RemoteEndpointMessageProperty.Name))
    {
        RemoteEndpointMessageProperty prop;
        prop = (RemoteEndpointMessageProperty)request.Properties[RemoteEndpointMessageProperty.Name];
        return prop.Address;
    }

    return null;
}

4
ধন্যবাদ, আমি এটিও খুঁজছিলাম গৌণ উন্নতি = সম্প্রসারণ শ্রেণি: gist.github.com/2653453
মাইক জ্যানসেন

28
ওয়েবএপিআই বেশিরভাগ অংশের জন্য খুব পরিষ্কার। এটি লজ্জার বিষয় যে আইপি হিসাবে তুচ্ছ কিছু করার জন্য এই জাতীয় কোডের প্রয়োজন।
টোড

2
RemoteEndpointMessagePropertyক্লাসটি কি System.ServiceModel.Channelsনামস্থান, System.ServiceModel.dllসমাবেশে? এটি কি ডাব্লুসিএফ-এর অন্তর্গত একটি সংসদ নয়?
স্লুমা

4
@ স্লুমা, হ্যাঁ, তারা। এএসপি.নেট ওয়েব এপিআই (বর্তমানে) দুটি "স্বাদে" প্রয়োগ করা হয়েছে, স্ব-হোস্টেড এবং ওয়েব-হোস্ট করা। ওয়েব-হোস্ট করা সংস্করণটি এএসপি.এনইটের শীর্ষে প্রয়োগ করা হয়েছে, অন্যদিকে ডাব্লুসিএফ শ্রোতার শীর্ষে স্ব-হোস্ট করা একটি। লক্ষ্য করুন যে প্ল্যাটফর্মটি (এএসপি.নেট ওয়েব এপিআই) নিজেই হোস্টিং-অজোনস্টিক, সুতরাং এটি সম্ভব যে ভবিষ্যতে কেউ একটি পৃথক হোস্টিং বাস্তবায়ন করবে এবং হোস্ট সেই সম্পত্তি (দূরবর্তী শেষের অবস্থান )টিকে আলাদাভাবে উপস্থাপন করবে।
কার্লোসফিগুইরা

3
দুর্ভাগ্যক্রমে, আপনি যদি ওউইনকে স্ব-হোস্ট করেন তবে এটি কার্যকর হয় না (যেমন এটি ওয়েব এপিআই 2 এর জন্য প্রস্তাবিত)। সেখানে থাকলে আর একটি দরকার ...
নিকোলাই সামতেলজে

74

এই সমাধানটি ওউইন ব্যবহার করে ওয়েব এপিআই-র স্ব-হোস্ট করাও কভার করে। আংশিকভাবে থেকে এখানে

আপনি নিজের মধ্যে এমন একটি ব্যক্তিগত পদ্ধতি তৈরি করতে পারেন ApiControllerযা আপনি কীভাবে আপনার ওয়েব এপিআই হোস্ট করেন তা দূরবর্তী আইপি ঠিকানাটি ফিরিয়ে দেবে:

 private const string HttpContext = "MS_HttpContext";
 private const string RemoteEndpointMessage =
     "System.ServiceModel.Channels.RemoteEndpointMessageProperty";
 private const string OwinContext = "MS_OwinContext";

 private string GetClientIp(HttpRequestMessage request)
 {
       // Web-hosting
       if (request.Properties.ContainsKey(HttpContext ))
       {
            HttpContextWrapper ctx = 
                (HttpContextWrapper)request.Properties[HttpContext];
            if (ctx != null)
            {
                return ctx.Request.UserHostAddress;
            }
       }

       // Self-hosting
       if (request.Properties.ContainsKey(RemoteEndpointMessage))
       {
            RemoteEndpointMessageProperty remoteEndpoint =
                (RemoteEndpointMessageProperty)request.Properties[RemoteEndpointMessage];
            if (remoteEndpoint != null)
            {
                return remoteEndpoint.Address;
            }
        }

       // Self-hosting using Owin
       if (request.Properties.ContainsKey(OwinContext))
       {
           OwinContext owinContext = (OwinContext)request.Properties[OwinContext];
           if (owinContext != null)
           {
               return owinContext.Request.RemoteIpAddress;
           }
       }

        return null;
 }

প্রয়োজনীয় তথ্যসূত্র:

  • HttpContextWrapper - System.Web.dll
  • RemoteEndpointMessageProperty - সিস্টেম.সেবারমোডেল.ডিএল
  • OwinContext - মাইক্রোসফট.উইন.ডিল (আপনি ওউইন প্যাকেজটি ব্যবহার করেন তবে ইতিমধ্যে এটি আপনার কাছে থাকবে)

এই সমাধানটির সাথে একটি সামান্য সমস্যা হ'ল আপনি যখন 3 টি ক্ষেত্রে ক্ষেত্রে লাইব্রেরি লোড করতে হয় তখন আপনি রানটাইমের সময় তাদের মধ্যে কেবল একটি ব্যবহার করবেন। এখানে প্রস্তাবিত হিসাবে , dynamicভেরিয়েবল ব্যবহার করে এটি কাটিয়ে উঠতে পারে । আপনি এর GetClientIpAddressএক্সটেনশন হিসাবে পদ্ধতিও লিখতে পারেন HttpRequestMethod

using System.Net.Http;

public static class HttpRequestMessageExtensions
{
    private const string HttpContext = "MS_HttpContext";
    private const string RemoteEndpointMessage =
        "System.ServiceModel.Channels.RemoteEndpointMessageProperty";
    private const string OwinContext = "MS_OwinContext";

    public static string GetClientIpAddress(this HttpRequestMessage request)
    {
       // Web-hosting. Needs reference to System.Web.dll
       if (request.Properties.ContainsKey(HttpContext))
       {
           dynamic ctx = request.Properties[HttpContext];
           if (ctx != null)
           {
               return ctx.Request.UserHostAddress;
           }
       }

       // Self-hosting. Needs reference to System.ServiceModel.dll. 
       if (request.Properties.ContainsKey(RemoteEndpointMessage))
       {
            dynamic remoteEndpoint = request.Properties[RemoteEndpointMessage];
            if (remoteEndpoint != null)
            {
                return remoteEndpoint.Address;
            }
        }

       // Self-hosting using Owin. Needs reference to Microsoft.Owin.dll. 
       if (request.Properties.ContainsKey(OwinContext))
       {
           dynamic owinContext = request.Properties[OwinContext];
           if (owinContext != null)
           {
               return owinContext.Request.RemoteIpAddress;
           }
       }

        return null;
    }
}

এখন আপনি এটি এর মতো ব্যবহার করতে পারেন:

public class TestController : ApiController
{
    [HttpPost]
    [ActionName("TestRemoteIp")]
    public string TestRemoteIp()
    {
        return Request.GetClientIpAddress();
    }
}

1
এই সমাধানটির কাজ করার জন্য এই নামস্থানটি "System.Net.Http" ব্যবহার করা উচিত। যেহেতু এটি অ্যাসেম্বলি সিস্টেমের একটি শ্রেণীর নাম e Web.Http.dll, v5.2.2.0।
ওয়াগনার বার্টোলিনি জুনিয়র

@ ওয়াগনারবার্টোলিনি, আপনার সঠিক, using System.Net.Http;আপনার প্রসারিত হওয়ায় আপনার লাইনের প্রয়োজন HttpRequestMessage। যদি না আপনি নিজের System.Net.Httpবর্ধনকে नेमস্পেসে সংজ্ঞায়িত না করেন যা খুব প্রশ্নবিদ্ধ। এটি যদিও প্রয়োজনীয় এটি নিশ্চিত নয়, কারণ এটি কোনও আইডিই বা উত্পাদনশীলতা সরঞ্জাম দ্বারা স্বয়ংক্রিয়ভাবে যুক্ত হবে। আপনি কি মনে করেন?
নিকোলাই সামতেলজে

আমি এখানে একটি কাজ শেষ করার তাগিদে ছিলাম এবং বিল্ড ত্রুটি কী চলছে তা দেখতে আমার 20 মিনিটের বেশি সময় লেগেছিল। আমি কেবল কোডটি অনুলিপি করেছিলাম এবং এর জন্য একটি ক্লাস তৈরি করেছি, সংকলন করার সময় এটি পদ্ধতিগুলি প্রদর্শন করছে না, যখন আমি ভিএস-তে "Go to সংজ্ঞা" ব্যবহার করি তা আমাকে আমার ক্লাসে নিয়ে যায়, এবং আমি কী করব তা বুঝতে পারি না যতক্ষণ না আমি অন্য শ্রেণি খুঁজে পেয়েছি। এক্সটেনশনগুলি একটি দুর্দান্ত নতুন বৈশিষ্ট্য এবং এটি সর্বদা ব্যবহৃত হয় না, যেহেতু, আমি মনে করি যে এই সময়টি সংরক্ষণ করা ভাল ধারণা হবে।
ওয়াগনার বার্টোলিনি জুনিয়র

1
Request.GetOwinContext () Request.RemoteIpAddress। OWIN ব্যবহার করার সময়, আপনি শুধু মত OWIN প্রসঙ্গ পেতে OwinHttpRequestMessageExtensions ব্যবহার করতে পারেন
Stef Heyenrath

1
এটি আসলে বর্ণ সিটিএক্স = অনুরোধ হওয়া উচিত rop প্রপার্টি [এমএসএইচটিটিপেক্সটেক্সট] এইচটিপিপেক্সটেক্সট্রাপার হিসাবে; EI আপনি যদি কাস্ট করেন তবে আপনাকে নাল পরীক্ষা করতে হবে না কারণ কাস্ট ব্যর্থ হলে আপনি একটি ব্যতিক্রম পাবেন
স্টেফ হেইনারথ

31

আপনি যদি সত্যিই ওয়ান-লাইনার চান এবং স্ব-হোস্ট ওয়েব এপিআইয়ের পরিকল্পনা না করেন:

((System.Web.HttpContextWrapper)Request.Properties["MS_HttpContext"]).Request.UserHostAddress;

13

উপরের উত্তরের জন্য সিস্টেমের একটি রেফারেন্স প্রয়োজন। ওয়েবটি এইচটিটিপি কনটেক্সট বা এইচটিটিপি কনটেক্সট র্র্যাপারে কাস্ট করতে সক্ষম হতে। আপনি যদি রেফারেন্সটি না চান, আপনি ডায়নামিক ব্যবহার করে আইপি পেতে সক্ষম হবেন:

var host = ((dynamic)request.Properties["MS_HttpContext"]).Request.UserHostAddress;

-1

কার্লোসফিগুইয়ের দ্বারা সরবরাহিত সমাধানটি কাজ করে, তবে টাইপ-নিরাপদ ওয়ান-লাইনারগুলি আরও ভাল: আপনার ক্রিয়া পদ্ধতিতে একটি using System.Webঅ্যাক্সেস যুক্ত করুন HttpContext.Current.Request.UserHostAddress


26
-1 এটিকে ওয়েব এপিআই-তে বিশ্বাস করা যায় HttpContext.Currentনা কারণ টাস্ক পাইপলাইন জুড়ে সঠিকভাবে অবিচল থাকে না; যেহেতু সমস্ত অনুরোধ পরিচালনা হ'ল অবিচ্ছিন্ন ous HttpContext.Currentওয়েব এপিআই কোড লেখার সময় প্রায় সর্বদা এড়ানো উচিত।
আন্দ্রেস জোল্টান

@ ইন্দ্রাস, আমি আরও বিস্তারিত জানতে চাই কেন এইচটিপিপন্টেক্সটেক্স ব্যবহার করা খারাপ? কেন আপনি এর জন্য কোনও মূল্যবান সংস্থান জানেন?
কিউংল

13
হাই @ কুংলি; প্রকৃতপক্ষে - থ্রেডিংয়ের সমস্যাটি সমস্যা হতে পারে (যদিও সবসময় সরাসরি যদি SynchronizationContextকাজগুলির মধ্যে সঠিকভাবে প্রবাহিত হয়); HttpContext.Currentএটির সাথে সবচেয়ে বড় সমস্যাটি হল যদি আপনার পরিষেবার কোডটি কখনও স্ব-হোস্টেড হওয়ার সম্ভাবনা থাকে (উদাহরণস্বরূপ, পরীক্ষা) - নিখুঁতভাবে Asp.Net নির্মিত হয় এবং যখন আপনি স্ব-হোস্ট করেন তখন তা উপস্থিত থাকে না।
আন্দ্রেস জোলটান

প্রকারের সুরক্ষা সব কিছু নয়। এই কোডটি NullReferenceExceptionযদি কোনও থ্রেড (উদাহরণস্বরূপ কোনও টাস্ক ওয়েটার, আধুনিক ওয়েব এপিআই কোডের মধ্যে খুব সাধারণ) বা স্ব-হোস্ট করা প্রসঙ্গে ব্যবহার করা হয় তবে হার্ড-ডিবাগ নিক্ষেপ করবে । কমপক্ষে অন্যান্য উত্তরগুলির মধ্যে বেশিরভাগই কেবল ফিরে আসবে null
অ্যারোনআউট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.