ASP.NET Core 'de HttpContext 'e erişmeAccess HttpContext in ASP.NET Core

Uygulamalar HttpContext , IHttpContextAccessor arabirim ve varsayılan uygulaması üzerinden erişim ASP.NET Core HttpContextAccessor .ASP.NET Core apps access HttpContext through the IHttpContextAccessor interface and its default implementation HttpContextAccessor. Yalnızca IHttpContextAccessor bir hizmetin içine erişmeniz gerektiğinde kullanılması gerekir HttpContext .It's only necessary to use IHttpContextAccessor when you need access to the HttpContext inside a service.

Sayfalardan HttpContext kullanın RazorUse HttpContext from Razor Pages

RazorSayfalar PageModel özelliği kullanıma sunar HttpContext :The Razor Pages PageModel exposes the HttpContext property:

public class AboutModel : PageModel
{
    public string Message { get; set; }

    public void OnGet()
    {
        Message = HttpContext.Request.PathBase;
    }
}

Bir görünümden HttpContext kullanma RazorUse HttpContext from a Razor view

Razorgörünümler, HttpContext görünümdeki bir Razor Page. Context özelliği aracılığıyla doğrudan kullanıma sunar.Razor views expose the HttpContext directly via a RazorPage.Context property on the view. Aşağıdaki örnek, Windows kimlik doğrulamasını kullanarak bir intranet uygulamasındaki geçerli kullanıcı adını alır:The following example retrieves the current username in an intranet app using Windows Authentication:

@{
    var username = Context.User.Identity.Name;
    
    ...
}

Bir denetleyiciden HttpContext kullanmaUse HttpContext from a controller

Denetleyiciler ControllerBase. HttpContext özelliğini kullanıma sunar:Controllers expose the ControllerBase.HttpContext property:

public class HomeController : Controller
{
    public IActionResult About()
    {
        var pathBase = HttpContext.Request.PathBase;

        ...

        return View();
    }
}

Ara yazılım içinden HttpContext kullanınUse HttpContext from middleware

Özel ara yazılım bileşenleriyle çalışırken, HttpContext Invoke veya InvokeAsync yöntemine geçirilir ve ara yazılım yapılandırıldığında erişilebilir:When working with custom middleware components, HttpContext is passed into the Invoke or InvokeAsync method and can be accessed when the middleware is configured:

public class MyCustomMiddleware
{
    public Task InvokeAsync(HttpContext context)
    {
        ...
    }
}

Özel bileşenlerden HttpContext kullanınUse HttpContext from custom components

İçin erişim gerektiren diğer Framework ve özel bileşenler için HttpContext Önerilen yaklaşım, yerleşik bağımlılık ekleme kapsayıcısını kullanarak bir bağımlılığı kaydetmek içindir.For other framework and custom components that require access to HttpContext, the recommended approach is to register a dependency using the built-in dependency injection container. Bağımlılık ekleme kapsayıcısı, öğesini IHttpContextAccessor oluşturucularının bir bağımlılığı olarak bildiren tüm sınıflara sağlar:The dependency injection container supplies the IHttpContextAccessor to any classes that declare it as a dependency in their constructors:

public void ConfigureServices(IServiceCollection services)
{
     services.AddControllersWithViews();
     services.AddHttpContextAccessor();
     services.AddTransient<IUserRepository, UserRepository>();
}
public void ConfigureServices(IServiceCollection services)
{
     services.AddMvc()
         .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
     services.AddHttpContextAccessor();
     services.AddTransient<IUserRepository, UserRepository>();
}

Aşağıdaki örnekte:In the following example:

  • UserRepository bağımlılığını bildirir IHttpContextAccessor .UserRepository declares its dependency on IHttpContextAccessor.
  • Bağımlılık ekleme, bağımlılık zincirini çözdüğünde ve bir örneği oluşturduğunda bağımlılık sağlanır UserRepository .The dependency is supplied when dependency injection resolves the dependency chain and creates an instance of UserRepository.
public class UserRepository : IUserRepository
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public UserRepository(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public void LogCurrentUser()
    {
        var username = _httpContextAccessor.HttpContext.User.Identity.Name;
        service.LogAccessRequest(username);
    }
}

Arka plan iş parçacığından HttpContext erişimiHttpContext access from a background thread

HttpContext iş parçacığı açısından güvenli değildir.HttpContext isn't thread-safe. Bir isteği işlemenin dışında okuma veya yazma özellikleri HttpContext bir ile sonuçlanabilir NullReferenceException .Reading or writing properties of the HttpContext outside of processing a request can result in a NullReferenceException.

Not

Uygulamanız tek tek, tek tek NullReferenceException Çoklu hatalar oluşturursa, arka plan işlemesini başlatan veya bir istek tamamlandıktan sonra işlemeye devam eden kodun bölümlerini gözden geçirin.If your app generates sporadic NullReferenceException errors, review parts of the code that start background processing or that continue processing after a request completes. Bir denetleyici metodunu olarak tanımlama gibi hataları arayın async void .Look for mistakes, such as defining a controller method as async void.

Verilerle arka planda çalışmayı güvenle gerçekleştirmek için HttpContext :To safely perform background work with HttpContext data:

  • İstek işleme sırasında gerekli verileri kopyalayın.Copy the required data during request processing.
  • Kopyalanmış verileri bir arka plan görevine geçirin.Pass the copied data to a background task.

Güvenli olmayan koddan kaçınmak için, HttpContext arka plan işini gerçekleştiren bir yönteme hiçbir şekilde geçirmeyin.To avoid unsafe code, never pass the HttpContext into a method that performs background work. Bunun yerine gerekli verileri geçirin.Pass the required data instead. Aşağıdaki örnekte, SendEmailCore bir e-posta göndermeye başlamak için çağırılır.In the following example, SendEmailCore is called to start sending an email. correlationIdÖğesine geçirilir, öğesine geçirilir SendEmailCore HttpContext .The correlationId is passed to SendEmailCore, not the HttpContext. Kod yürütme işleminin tamamlanmasını beketmez SendEmailCore :Code execution doesn't wait for SendEmailCore to complete:

public class EmailController : Controller
{
    public IActionResult SendEmail(string email)
    {
        var correlationId = HttpContext.Request.Headers["x-correlation-id"].ToString();

        _ = SendEmailCore(correlationId);

        return View();
    }

    private async Task SendEmailCore(string correlationId)
    {
        ...
    }
}

Blazor ve paylaşılan durumBlazor and shared state

Sunucu Blazor sunucu uygulamaları canlı.Blazor server apps live in server memory. Diğer bir deyişle, aynı işlem içinde barındırılan birden çok uygulama vardır.That means that there are multiple apps hosted within the same process. Her uygulama oturumunda, Blazor kendi dı kapsayıcı kapsamı ile bir devre başlatır.For each app session, Blazor starts a circuit with its own DI container scope. Bu, kapsamlı hizmetlerin Blazor oturumu başına benzersiz olduğu anlamına gelir.That means that scoped services are unique per Blazor session.

Uyarı

Bu durum, çok sayıda kullanıcı durumunun sızması gibi güvenlik açıklarını ortaya çıkaracak şekilde, aşırı bakım alınmadığı sürece aynı sunucu paylaşma durumunda uygulamalar önermemektedir.We don't recommend apps on the same server share state using singleton services unless extreme care is taken, as this can introduce security vulnerabilities, such as leaking user state across circuits.

Blazor uygulamalarında durum bilgisi olan Singleton Hizmetleri, özellikle kendisi için tasarlandıklarında kullanabilirsiniz.You can use stateful singleton services in Blazor apps if they are specifically designed for it. Örneğin, belirli bir girdiye erişmek için bir anahtar gerektirdiğinden bir bellek önbelleğinin tek bir şekilde kullanılması, kullanıcıların hangi önbellek anahtarlarının kullanıldıklarını denetleyemediği varsayılarak, bu bir değer olarak kullanılabilir.For example, it's ok to use a memory cache as a singleton because it requires a key to access a given entry, assuming users don't have control of what cache keys are used.

Ek olarak, güvenlik nedenleriyle, IHttpContextAccessor Blazor Apps içinde kullanmamalıdır.Additionally, again for security reasons, you must not use IHttpContextAccessor within Blazor apps. Blazor uygulamaları ASP.NET Core işlem hattı bağlamı dışında çalışır.Blazor apps run outside of the context of the ASP.NET Core pipeline. HttpContextİçinde kullanılabilir olmadığı garanti edilmez ve IHttpContextAccessor Blazor uygulamasını Başlatan bağlamını tutan garanti edilmez.The HttpContext isn't guaranteed to be available within the IHttpContextAccessor, nor is it guaranteed to be holding the context that started the Blazor app.

İstek durumunu Blazor uygulamasına geçirmek için önerilen yol, uygulamanın ilk işlemede kök bileşene parametreler kullanmaktır:The recommended way to pass request state to the Blazor app is through parameters to the root component in the initial rendering of the app:

  • Blazor uygulamasına geçirmek istediğiniz tüm verileri içeren bir sınıf tanımlayın.Define a class with all the data you want to pass to the Blazor app.
  • Bu verileri Razor sayfasından, HttpContext Bu sırada kullanılabilir olan ' i kullanarak doldurun.Populate that data from the Razor page using the HttpContext available at that time.
  • Verileri Blazor uygulamasına kök bileşene (uygulama) bir parametre olarak geçirin.Pass the data to the Blazor app as a parameter to the root component (App).
  • Uygulamaya geçirilen verileri tutmak için kök bileşende bir parametre tanımlayın.Define a parameter in the root component to hold the data being passed to the app.
  • Uygulama içinde kullanıcıya özgü verileri kullanın; Alternatif olarak, bu verileri OnInitializedAsync uygulama genelinde kullanılabilmesi için içindeki kapsamlı bir hizmete kopyalayın.Use the user-specific data within the app; or alternatively, copy that data into a scoped service within OnInitializedAsync so that it can be used across the app.

Daha fazla bilgi ve örnek kod için bkz ASP.NET Core Blazor Server ek güvenlik senaryoları ..For more information and example code, see ASP.NET Core Blazor Server ek güvenlik senaryoları.