ASP.NET Core Web

※This article is based on .NET 7

概要 [edit]

ASP.NET Core应用开发中使用频率最高的对象。要说明HttpContext的本质,还得从请求处理管道的层面来讲。

对于由一个服务器和多个中间件构建的管道来说,面向传输层的服务器负责请求的监听、接收和最终的响应,当它接收到客户端发送的请求后,需要将它分发给后续中间件进行处理。

对于某个中间件来说,当我们完成了自身的请求处理任务之后,在大部分情况下也需要将请求分发给后续的中间件。请求在服务器与中间件之间,以及在中间件之间的分发是通过共享上下文的方式实现的。

当服务器接收到请求之后,会创建一个通过HttpContext表示的上下文对象,所有中间件都是在这个上下文中处理请求的,那么一个HttpContext对象究竟携带怎样的上下文信息呢?

举例 [edit]

我们知道一个HTTP事务(Transaction)具有非常清晰的界定,即接收请求、发送响应,所以请求和响应是两个基本的要素,也是HttpContext承载的最核心的上下文信息。

我们可以将请求理解为输入、响应理解为输出,所以应用程序可以利用HttpContext得到当前请求所有的输入信息,也可以利用它完成我们所需的所有输出工作。为此我们为ASP.NET Core Mini定义了如下这个极简版本的HttpContext。

public class HttpContext
{           
    public  HttpRequest Request { get; }
    public  HttpResponse Response { get; }
}
public class HttpRequest
{
    public  Uri Url { get; }
    public  NameValueCollection Headers { get; }
    public  Stream Body { get; }
}
public class HttpResponse
{
    public  NameValueCollection Headers { get; }
    public  Stream Body { get; }
    public int StatusCode { get; set;}
}

如上面的代码片段所示,HttpContext通过它的两个属性Request和Response来表示请求和响应,它们对应的类型分别为HttpRequest和HttpResponse。通过前者,我们可以得到请求的地址、手部集合和主体内容,利用后者,我们可以设置响应状态码,也可以设置首部和主体内容。

调用HttpContext [edit]

在 ASP.NET Core 中要想得到 cookie 必须要有 Request 对象,要想得到 Request 对象 必须要有 HttpContext,要想得到 HttpContext 必须要利用 IHttpContextAccessor 接口

ASP.NET Core 中就内置了一个实现了该接口的 HttpContextAccessor 类

命名空间:Microsoft.AspNetCore.Http
程序集:Microsoft.AspNetCore.Http.Abstractions.dll
包:Microsoft.AspNetCore.App.Ref v7.0.5
public interface IHttpContextAccessor
{
    HttpContext HttpContext { get; set; }
}

内置标准方法 [edit]

依赖注入 [edit]

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    //IHttpContextAccessor register
    services.AddHttpContextAccessor();
    services.AddTransient<IUserService, UserService>();
}

使用 [edit]

将 IHttpContextAccessor 注入到创建的服务构造函数中,并访问 HttpContext 的属性,如下所示:

namespace Get_HttpContext_ASP.NET_Core
{
    using Microsoft.AspNetCore.Http;

    public class UserService : IUserService
    {
        private readonly IHttpContextAccessor _httpContextAccessor;

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

        public string GetLoginUserName()
        {
            return _httpContextAccessor.HttpContext.User.Identity.Name;
        }
    }
}
https://www.telerik.com/blogs/how-to-get-httpcontext-asp-net-core

进阶方法 [edit]

不直接使用父类 Controller 的 Request 和 HttpContext,这是因为此方式是一种强依赖,接下来给大家演示如何通过依赖注入的方式获取 HttpContext,此种更加灵活。

依赖注入 [edit]

自定义一个Accessor

public class HttpContextAccessor : IHttpContextAccessor
{
    public HttpContextAccessor();
    public HttpContext HttpContext { get; set; }
}

为了实现依赖注入,需要将 IHttpContextAccessor 和 HttpContextAccessor 注入到 ServiceCollection 中,下面就用单例的模式进行注入

public void ConfigureServices(IServiceCollection services)
{
	services.AddSingleton<IHttpContextAccessor,HttpContextAccessor>();
	// 逻辑代码
}

写入 [edit]

然后就可以通过依赖注入的方式获取 IHttpContextAccessor 接口的实例,再依次获取 HttpContext 对象,下面的代码片段展示了如何在 Controller 中访问 IHttpContextAccessor 实例

public class HomeController : Controller
{
    private readonly IHttpContextAccessor _httpContextAccessor;
    public HomeController(IHttpContextAccessor httpContextAccessor)
    {
        this._httpContextAccessor = httpContextAccessor;
    }   

    //写入Cookie
    public IActionResult Write(string key, string value, bool isPersistent)
    {
    	CookieOptions options = new CookieOptions();
    	if (isPersistent)
    		options.Expires = DateTime.Now.AddDays(1);
    	else
    		options.Expires = DateTime.Now.AddSeconds(10);
    	_httpContextAccessor.HttpContext.Response.Cookies.Append(key, value, options);
    	return View("WriteCookie");
    }  
}

读取 [edit]

public IActionResult Read(string key)
{
	ViewBag.Data = _httpContextAccessor.HttpContext.Request.Cookies[key];
	return View("ReadCookie");
}

コメント:



(画像の文字列を入力して下さい)

トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS