详解Asp.Net Core中的Cookies

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 目录详解Asp.Net Core中的cookies搞懂cookiesAsp.Net中cookies的实现从http中获取cookies将cookies写入http中总结及感想详解Asp.Net Core中的cookies搞懂cookies我之前写过一篇文章来介绍cookies,如果你对cookies不是很了解请移步理解cookies这篇文章,这对于我们研究asp.net core中的cookies可以起到很大的帮助。

目录

详解Asp.Net Core中的cookies

搞懂cookies

我之前写过一篇文章来介绍cookies,如果你对cookies不是很了解请移步理解cookies这篇文章,这对于我们研究asp.net core中的cookies可以起到很大的帮助。

Asp.Net中cookies的实现

cookies是http协议中header头的一部分,服务器与客户端的cookies传递都是通过header头完成的,那么asp.net core只不过是对http协议的一种实现而已。

从http中获取cookies

要从http中获取cookies,首先我们要获取header头信息,而这部分信息asp.net core已经为我们准备好了,并且也帮我们解析了header头中cookies,我们只需要通过HttpContext.Request.Cookies就可以获取所有的cookies信息。

接下来我们主要研究一下asp.net core是如何做的,在这里语言是否显得苍白许多,我们尽量以贴代码为主:

public abstract class HttpRequest
{
    ...
    public abstract IRequestCookieCollection Cookies { get; set; }
    ...
}

从代码可以可看出Cookies是一个IRequestCookieCollection接口类型,它的实现类型为RequestCookieCollection,接口代码如下:

//从接口代码看该类是一个只读类,为什么会是只读类,这也不难理解,Request是一个请求对象,也就是客户端发往服务器的数据,因为这些数据是供我们来读取验证用的,所以修改并没有什么意义
public interface IRequestCookieCollection : IEnumerable<KeyValuePair<string, string>>, IEnumerable
{
    string this[string key] { get; }
    int Count { get; }
    ICollection<string> Keys { get; }
    bool ContainsKey(string key);
    bool TryGetValue(string key, out string value);
}
  • 然后,我们再来分析header中的cookies是如何被解析到Request中的Cookies对象的

    DefaultHttpRequest是如何实现HttpRequest的:

    public class DefaultHttpRequest : HttpRequest
    {
      ...
    
      //这是一个委托对象,用于生成RequestCookiesFeature实例
      private readonly static Func<IFeatureCollection, IRequestCookiesFeature> _newRequestCookiesFeature = f => new RequestCookiesFeature(f);
      ...
    
      //这个方法属性展示了如何去实例化RequestCookiesFeature对象
        private IRequestCookiesFeature RequestCookiesFeature =>_features.Fetch(ref _features.Cache.Cookies, _newRequestCookiesFeature);
    
        //这里直接调用RequestCookiesFeature
        public override IRequestCookieCollection Cookies
        {
          get { return RequestCookiesFeature.Cookies; }
          set { RequestCookiesFeature.Cookies = value; }
        }
    }

    RequestCookiesFeature.Cookies才是真正触发cookies解析的地方:

     public class RequestCookiesFeature : IRequestCookiesFeature
     {
      public IRequestCookieCollection Cookies
        {
           get
           {
              ...
              //从请求中获取header信息,headers是一个IDictionary<string,StringValues>类型
              var headers = HttpRequestFeature.Headers;
              StringValues current;
              //从headers字典类型中获取cookies的信息,这里获取的current结果是个字符串类型
              if (!headers.TryGetValue(HeaderNames.Cookie, out current))
              {
                  current = string.Empty;
              }
    
              if (_parsedValues == null || _original != current)
              {
                  _original = current;
                  //这里开始将cookies字符串解析为cookies集合类型
                  _parsedValues = RequestCookieCollection.Parse(current.ToArray());
              }
         }
    }
    
    //RequestCookieCollection.Parse代码如下:
    public class RequestCookieCollection : IRequestCookieCollection
    {
      public static RequestCookieCollection Parse(IList<string> values)
        {
          ...
             IList<CookieHeaderValue> cookies;
             //最有用的一句代码在这里,将字符串集合解析为IList<CookieHeaderValue>
             if (CookieHeaderValue.TryParseList(values, out cookies))
             {
                  ...
             }
             ...
          }
    
    }
  • 最终,CookieHeaderParser才是真正干活的地方:

 internal class CookieHeaderParser : HttpHeaderParser<CookieHeaderValue>
 {
  public sealed override bool TryParseValue(StringSegment value, ref int index, out CookieHeaderValue parsedValue)
    {
      ...
    }
 }

将cookies写入http中

  • 我们先来看看Response.Cookies.Append是如何实现的

    Response.Cookies是一个HttpRespnse对象,而ResponseCookies则是IResponseCookies的默认实现

public class ResponseCookies : IResponseCookies
{   
    //通过Append方法来添加cookie
    public void Append(string key, string value)
    {
        //这里构造一个cookie对象
        var setCookieHeaderValue = new SetCookieHeaderValue(
            Uri.EscapeDataString(key),
            Uri.EscapeDataString(value))
            {
                Path = "/"
            };
        //然后cookie对象序列化字符串,因为在http协议中cookie的值就是字符串
        var cookieValue = setCookieHeaderValue.ToString();
        //最后将cookie字符串添加到Headers中,StringValues.Concat将两个字符串转换成string[]
        //Headers是个字典类型,所有header中数据都是以k-v的形式保存在这个字典中
        Headers[HeaderNames.SetCookie] = StringValues.Concat(Headers[HeaderNames.SetCookie], cookieValue);
        }
  • 看一下Headers的实现

    HttpResponseHeaders负责将header信息写入响应流

    public partial class HttpResponseHeaders : HttpHeaders
    { 
       internal void CopyTo(ref BufferWriter<PipeWriter> buffer)
            {
              //这个方将负责将headers通过流的形式写入响应结果        
                CopyToFast(ref buffer);
                ...
            }
    }

总结及感想

​ 本文介绍了,我对cookies的理解,以及asp.net core中cookies是怎么实现的,对于所有web框架的实现都是大同小异的,如果还有什么不明的地方最好自己能多读几遍代码,多看多思考,最总一切问题都会迎刃而解。

目录
相关文章
|
8天前
|
开发框架 .NET 开发者
简化 ASP.NET Core 依赖注入(DI)注册-Scrutor
Scrutor 是一个简化 ASP.NET Core 应用程序中依赖注入(DI)注册过程的开源库,支持自动扫描和注册服务。通过简单的配置,开发者可以轻松地从指定程序集中筛选、注册服务,并设置其生命周期,同时支持服务装饰等高级功能。适用于大型项目,提高代码的可维护性和简洁性。仓库地址:&lt;https://github.com/khellang/Scrutor&gt;
30 5
|
26天前
|
开发框架 .NET C#
在 ASP.NET Core 中创建 gRPC 客户端和服务器
本文介绍了如何使用 gRPC 框架搭建一个简单的“Hello World”示例。首先创建了一个名为 GrpcDemo 的解决方案,其中包含一个 gRPC 服务端项目 GrpcServer 和一个客户端项目 GrpcClient。服务端通过定义 `greeter.proto` 文件中的服务和消息类型,实现了一个简单的问候服务 `GreeterService`。客户端则通过 gRPC 客户端库连接到服务端并调用其 `SayHello` 方法,展示了 gRPC 在 C# 中的基本使用方法。
38 5
在 ASP.NET Core 中创建 gRPC 客户端和服务器
|
16天前
|
开发框架 缓存 .NET
GraphQL 与 ASP.NET Core 集成:从入门到精通
本文详细介绍了如何在ASP.NET Core中集成GraphQL,包括安装必要的NuGet包、创建GraphQL Schema、配置GraphQL服务等步骤。同时,文章还探讨了常见问题及其解决方法,如处理复杂查询、错误处理、性能优化和实现认证授权等,旨在帮助开发者构建灵活且高效的API。
24 3
|
2月前
|
开发框架 JavaScript 前端开发
一个适用于 ASP.NET Core 的轻量级插件框架
一个适用于 ASP.NET Core 的轻量级插件框架
|
3月前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
48 7
|
3月前
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
75 0
|
4月前
|
开发框架 前端开发 .NET
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
56 0
|
4月前
|
开发框架 前端开发 安全
ASP.NET MVC 如何使用 Form Authentication?
ASP.NET MVC 如何使用 Form Authentication?
|
4月前
|
开发框架 .NET
Asp.Net Core 使用X.PagedList.Mvc.Core分页 & 搜索
Asp.Net Core 使用X.PagedList.Mvc.Core分页 & 搜索
143 0
|
7月前
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
212 0