এএসপি.এনইটি কোর-এ বর্তমান এইচটিটিপি কনটেক্সট অ্যাক্সেস করুন


132

আমার HttpContextকোনও স্থিতিশীল পদ্ধতি বা কোনও ইউটিলিটি পরিষেবাতে বর্তমান অ্যাক্সেস করা দরকার ।

ক্লাসিক এএসপি.নেট এমভিসি সহ এবং System.Web, আমি কেবল HttpContext.Currentস্ট্যাটিকভাবে প্রসঙ্গটি অ্যাক্সেস করতে ব্যবহার করব । তবে আমি কীভাবে এএসপি.নেট কোর এ করব?

উত্তর:


149

HttpContext.Currentএএসপি.নেট কোরটিতে আর অস্তিত্ব নেই তবে এমন একটি নতুন বিষয় রয়েছে IHttpContextAccessorযা আপনি আপনার নির্ভরতাতে ইনজেকশন করতে পারেন এবং বর্তমানটি পুনরুদ্ধার করতে ব্যবহার করতে পারেন HttpContext:

public class MyComponent : IMyComponent
{
    private readonly IHttpContextAccessor _contextAccessor;

    public MyComponent(IHttpContextAccessor contextAccessor)
    {
        _contextAccessor = contextAccessor;
    }

    public string GetDataFromSession()
    {
        return _contextAccessor.HttpContext.Session.GetString(*KEY*);
    }
}

3
ভাল যুক্তি! এটিও উল্লেখ করার মতো যে IHttpContextAccessorএটি কেবলমাত্র ডিআই কনটেইনারটি সমাধান করে এমন জায়গায় পাওয়া যাবে।
tugberk

6
@tugberk ভাল, তত্ত্ব, এছাড়াও আপনি ব্যবহার করতে পারে CallContextServiceLocatorএমনকি একটি অ-di-ইনজেকশনের উদাহরণস্বরূপ থেকে, একটি পরিষেবা সমাধান করতে: CallContextServiceLocator.Locator.ServiceProvider.GetService<IHttpContextAccessor>()। অনুশীলনে, এটি এড়াতে
পারলে


9
@ ডেভিডফাউল যদি আপনার বৈধ প্রযুক্তিগত কারণ না থাকে ('স্ট্যাটিকসটি মন্দ হয়' বাদে অবশ্যই), আমি বাজি রাখি যে লোকেরা যদি তাদের অন্য কোনও পছন্দ না করে তবে এটি ব্যবহার করবে।
কেভিন চ্যাট

7
অবশ্যই, লোকজনের কাছে একটি বৈধ প্রযুক্তিগত কারণ খুব কমই রয়েছে। এটি আরও ভাল যেমন স্ট্যাটিক ব্যবহার করা সহজ এবং যিনি
টেস্টাবিলিটি

35

Necromancing।
হ্যাঁ আপনি
বড় মাইগ্রেশন করার জন্য গোপন পরামর্শ করতে পারেনjunksকোডের অংশগুলি (দীর্ঘশ্বাস, ফ্রয়েডিয়ান স্লিপ)।
নিম্নলিখিত পদ্ধতিটি হ্যাকের একটি অশুভ কার্বঙ্কাল যা শয়তানের এক্সপ্রেশন কাজ (। নেট কোর ফ্রেমওয়ার্ক বিকাশকারীদের দৃষ্টিতে) চালিত করতে সক্রিয়ভাবে নিযুক্ত রয়েছে, তবে এটি কার্যকর করে :

ভিতরে public class Startup

একটি সম্পত্তি যুক্ত করুন

public IConfigurationRoot Configuration { get; }

এবং তারপরে কনফিগার সার্ভিসগুলিতে ডিআই-তে একটি সিঙ্গলটন আইএইচটিটিপেক্সটেক্সট এ্যাকসেসর যুক্ত করুন।

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<Microsoft.AspNetCore.Http.IHttpContextAccessor, Microsoft.AspNetCore.Http.HttpContextAccessor>();

তারপরে কনফিগার করুন

    public void Configure(
              IApplicationBuilder app
             ,IHostingEnvironment env
             ,ILoggerFactory loggerFactory
    )
    {

ডিআই প্যারামিটার যুক্ত করুন IServiceProvider svp, সুতরাং পদ্ধতিটি দেখে মনে হচ্ছে:

    public void Configure(
           IApplicationBuilder app
          ,IHostingEnvironment env
          ,ILoggerFactory loggerFactory
          ,IServiceProvider svp)
    {

এর পরে, সিস্টেমের জন্য একটি প্রতিস্থাপন শ্রেণি তৈরি করুন e ওয়েব:

namespace System.Web
{

    namespace Hosting
    {
        public static class HostingEnvironment 
        {
            public static bool m_IsHosted;

            static HostingEnvironment()
            {
                m_IsHosted = false;
            }

            public static bool IsHosted
            {
                get
                {
                    return m_IsHosted;
                }
            }
        }
    }


    public static class HttpContext
    {
        public static IServiceProvider ServiceProvider;

        static HttpContext()
        { }


        public static Microsoft.AspNetCore.Http.HttpContext Current
        {
            get
            {
                // var factory2 = ServiceProvider.GetService<Microsoft.AspNetCore.Http.IHttpContextAccessor>();
                object factory = ServiceProvider.GetService(typeof(Microsoft.AspNetCore.Http.IHttpContextAccessor));

                // Microsoft.AspNetCore.Http.HttpContextAccessor fac =(Microsoft.AspNetCore.Http.HttpContextAccessor)factory;
                Microsoft.AspNetCore.Http.HttpContext context = ((Microsoft.AspNetCore.Http.HttpContextAccessor)factory).HttpContext;
                // context.Response.WriteAsync("Test");

                return context;
            }
        }


    } // End Class HttpContext 


}

এখন কনফিগার করুন, যেখানে আপনি IServiceProvider svpএই পরিষেবা সরবরাহকারীটিকে সদ্য তৈরি করা ডামি ক্লাস সিস্টেম.সাহেব.এইচটিপি কনটেক্সট (সিস্টেম.ওয়েব.এইচটিপি কনটেক্সটস.সেস্প্রোভাইডার) এ স্ট্যাটিক ভেরিয়েবল "সার্ভিসপ্রোভাডার" এ সংরক্ষণ করুন)

এবং হোস্টিংএন্টারভায়রনমেন্টস.আইএস হোস্টেড সত্য হিসাবে সেট করুন

System.Web.Hosting.HostingEnvironment.m_IsHosted = true;

এটি মূলত সিস্টেম W ওয়েবেই করেছে যা আপনি কখনও দেখেননি (আমার ধারণা ভেরিয়েবলটি পাবলিকের পরিবর্তে অভ্যন্তরীণ হিসাবে ঘোষণা করা হয়েছিল)।

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IServiceProvider svp)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();

    ServiceProvider = svp;
    System.Web.HttpContext.ServiceProvider = svp;
    System.Web.Hosting.HostingEnvironment.m_IsHosted = true;


    app.UseCookieAuthentication(new CookieAuthenticationOptions()
    {
        AuthenticationScheme = "MyCookieMiddlewareInstance",
        LoginPath = new Microsoft.AspNetCore.Http.PathString("/Account/Unauthorized/"),
        AccessDeniedPath = new Microsoft.AspNetCore.Http.PathString("/Account/Forbidden/"),
        AutomaticAuthenticate = true,
        AutomaticChallenge = true,
        CookieSecure = Microsoft.AspNetCore.Http.CookieSecurePolicy.SameAsRequest

       , CookieHttpOnly=false

    });

ASP.NET ওয়েব ফরম মতো, আপনি একটি NullReference যখন আপনি অ্যাক্সেস করার চেষ্টা করছেন পাবেন একটি HttpContext যখন কেউ নেই, যেমন এতে ব্যবহার করা হয় Application_Startglobal.asax হবে।

আমি আবারও জোর দিয়েছি, আপনি কেবল যুক্ত করলে এটি কেবল কাজ করে works

services.AddSingleton<Microsoft.AspNetCore.Http.IHttpContextAccessor, Microsoft.AspNetCore.Http.HttpContextAccessor>();

যেমনটা আমি লিখেছি তোমার উচিত।
ডিআই প্যাটার্নের মধ্যে সার্ভিসলোকেটার প্যাটার্নে আপনাকে স্বাগতম;)
ঝুঁকি এবং পার্শ্ব প্রতিক্রিয়াগুলির জন্য, আপনার আবাসিক চিকিৎসক বা ফার্মাসিস্টকে জিজ্ঞাসা করুন - বা github.com/aspnet এ .NET কোর এর উত্সগুলি অধ্যয়ন করুন এবং কিছু পরীক্ষা করুন।


সম্ভবত আরও বেশি রক্ষণাবেক্ষণের পদ্ধতিতে এই সহায়ক শ্রেণিটি যুক্ত করা হবে

namespace System.Web
{

    public static class HttpContext
    {
        private static Microsoft.AspNetCore.Http.IHttpContextAccessor m_httpContextAccessor;


        public static void Configure(Microsoft.AspNetCore.Http.IHttpContextAccessor httpContextAccessor)
        {
            m_httpContextAccessor = httpContextAccessor;
        }


        public static Microsoft.AspNetCore.Http.HttpContext Current
        {
            get
            {
                return m_httpContextAccessor.HttpContext;
            }
        }


    }


}

এবং তারপরে স্টার্টআপ-> কনফিগারে HTTPContext.Configure- এ কল করুন

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IServiceProvider svp)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();


    System.Web.HttpContext.Configure(app.ApplicationServices.
        GetRequiredService<Microsoft.AspNetCore.Http.IHttpContextAccessor>()
    );

37
এই খাঁটি দুর্লভ
আর্ট

2
সহায়ক পদ্ধতির সংস্করণটি প্রতিটি দৃশ্যে সঠিকভাবে কাজ করে? মাল্টিথ্রেডিং, অ্যাসিঙ্ক এবং আইওসি পাত্রে বিভিন্ন জীবনকালের সাথে পরিষেবাগুলির কথা চিন্তা করছেন?
তামাস মোলনার

7
আমি জানি আমরা সবাইকে এটা কতটা নির্দয়ভাবে ডায়াবলিকাল তা বোঝাতে আমাদের পথের বাইরে যেতে হবে ... তবে আপনি যদি কোরে একটি বিশাল প্রকল্প বন্দর করছিলেন, যেখানে এইচটিটিপি কনটেক্সট.কেন্নরটি কিছু শক্ত-টু-পৌঁছনো স্ট্যাটিক শ্রেণিতে ব্যবহৃত হত .. এটি সম্ভবত বেশ কার্যকর হবে। সেখানে, আমি এটা বলেছি।
ব্রায়ান

2
এটি খাঁটি মন্দ ... এবং উপযুক্ত যে আমি এটি হ্যালোইনে প্রয়োগ করব। আমি ডিআই এবং আইওসি পছন্দ করি ... তবে আমি মন্দ স্ট্যাটিক ক্লাসগুলির সাথে খারাপ স্ট্যাটিক ভেরিয়েবলগুলির সাথে একটি উত্তরাধিকার অ্যাপ্লিকেশনটির সাথে কাজ করছি, যা আমাদের কেস্টরেল ব্যবহার করে ধাক্কা দেওয়া দরকার এবং এইচটিটিপি কনটেক্সটকে ইনজেকশন দেওয়ার চেষ্টা করা আমাদের জন্য সমস্ত কিছু ভঙ্গ না করে কেবল অগ্রহণযোগ্য হবে।
হাউস অফ ডেক্সটার

2
হ্যাঁ, এটি মাইগ্রেশনগুলির সঠিক উত্তর। ;)
টম স্টিকেল 4'19

23

কেবলমাত্র অন্য উত্তরে যুক্ত করতে ...

ASP.NET কোর 2.1, সেখানে এর এক্সটেনশন পদ্ধতি , যে নাম নিবন্ধন করতে পারবেন সঠিক জীবদ্দশায় সঙ্গেAddHttpContextAccessorIHttpContextAccessor

public void ConfigureServices(IServiceCollection services)
{
    services.AddHttpContextAccessor();

    // Other code...
}

2
শয়তানী কার্বঙ্কালের আরও সরকারী বিকল্প দেখে খুশি!
কেন লিয়ন

@ কেন লিয়ন:;) খেলাং: সিঙ্গলটন সঠিক জীবনকাল। Scoped ভুল হবে। বা লেখার সময় খুব কম সময়েই তা ছিল। তবে আরও ভাল যদি অ্যাডএইচটিপিপেক্সটেক্সট্যাক্সেসর আমাদের নির্দিষ্ট কাঠামোর সংস্করণের জন্য কোনও রেফারেন্সের প্রয়োজন ছাড়াই এটি সঠিকভাবে করে।
স্টিফান স্টেইগার

আপনি একটি উদাহরণ ভাগ করতে পারেন?
টুলকিট

@ টুলকিট কিছু উদাহরণ কোড যুক্ত করেছে। যদিও উপরের পাঠ্যের উপরে এটি কোন মান সরবরাহ করে তা নিশ্চিত নয়।
খেলাং

22

আমি যে সবচেয়ে বৈধ উপায় নিয়ে এসেছি তা হ'ল আপনার স্থিতিশীল প্রয়োগে IHttpContextAccessor ইনজেকশনের মাধ্যমে নিম্নরূপ:

public static class HttpHelper
{
     private static IHttpContextAccessor _accessor;
     public static void Configure(IHttpContextAccessor httpContextAccessor)
     {
          _accessor = httpContextAccessor;
     }

     public static HttpContext HttpContext => _accessor.HttpContext;
}

তারপরে স্টার্টআপ কনফিগারে আইএইচটিপিপেক্সটেক্সট অ্যাকসেসর নিয়োগের কাজটি করা উচিত।

HttpHelper.Configure(app.ApplicationServices.GetRequiredService<IHttpContextAccessor>());

আমার ধারণা, আপনার সার্ভিস সিঙ্গলটনে নিবন্ধন করতে হবে:

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

সুন্দর। ঠিক কী ডাক্তার আদেশ করলেন!
শ্রাপনুল

5

এই নিবন্ধ অনুসারে: ASP.NET কোর মধ্যে কাঠামোর উপাদানগুলির বাইরে HttpContext অ্যাক্সেস করা

namespace System.Web
{
    public static class HttpContext
    {
        private static IHttpContextAccessor _contextAccessor;

        public static Microsoft.AspNetCore.Http.HttpContext Current => _contextAccessor.HttpContext;

        internal static void Configure(IHttpContextAccessor contextAccessor)
        {
            _contextAccessor = contextAccessor;
        }
    }
}

তারপর:

public static class StaticHttpContextExtensions
{
    public static void AddHttpContextAccessor(this IServiceCollection services)
    {
        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    }

    public static IApplicationBuilder UseStaticHttpContext(this IApplicationBuilder app)
    {
        var httpContextAccessor = app.ApplicationServices.GetRequiredService<IHttpContextAccessor>();
        System.Web.HttpContext.Configure(httpContextAccessor);
        return app;
    }
}

তারপর:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddHttpContextAccessor();
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseStaticHttpContext();
        app.UseMvc();
    }
}

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

using System.Web;

public class MyService
{
   public void DoWork()
   {
    var context = HttpContext.Current;
    // continue with context instance
   }
}

2

স্টার্টআপে

services.AddHttpContextAccessor();

নিয়ামক মধ্যে

public class HomeController : Controller
    {
        private readonly IHttpContextAccessor _context;

        public HomeController(IHttpContextAccessor context)
        {
            _context = context; 
        }
        public IActionResult Index()
        {
           var context = _context.HttpContext.Request.Headers.ToList();
           return View();
        }
   }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.