zoukankan      html  css  js  c++  java
  • 在 .NET 开发中请不要序列化 CookieCollection 和 Cookie 对象

    笔者之前的文章:摒弃反射:.NET 6 为序列化 CookieContainer 提供了新方法 中所使用的代码对 CookieCollection 对象进行了 JSON 序列化。在该文章发布后笔者对该项目所用的技术投入了实战,然而并不成功。

    假设有以下代码:

    var cookie = new CookieContainer();
        cookie.Add(new Cookie("c1", "v1", "/", "httpbin.org"));
        cookie.Add(new Cookie("c2", "v2", "/", "httpbin.org"));
        cookie.Add(new Cookie("c3", "v3", "/", "httpbin.org"));
        cookie.Add(new Cookie("c4", "v4", "/", "httpbin.org"));
        var http = new HttpClient(new HttpClientHandler
        {
            UseCookies = true,
            CookieContainer = cookie
        });
        var ret = await http.GetStringAsync("https://httpbin.org/cookies");
        Console.WriteLine(ret);
    

    这会产生正常的输出:

    {
          "cookies": {
            "c1": "v1",
            "c2": "v2",
            "c3": "v3",
            "c4": "v4"
          }
    }
    

    下面的代码会将一个 CookieCollection 序列化为 JSON 字符串:

    static string GetJson()
    {
        var cookie = new CookieContainer();
        cookie.Add(new Cookie("c1", "v1", "/", "httpbin.org"));
        cookie.Add(new Cookie("c2", "v2", "/", "httpbin.org"));
        cookie.Add(new Cookie("c3", "v3", "/", "httpbin.org"));
        cookie.Add(new Cookie("c4", "v4", "/", "httpbin.org"));
        var collection = cookie.GetAllCookies();
        var json = JsonConvert.SerializeObject(collection);
        return json;
    }
    

    使用反序列化并构造请求:

        var cookie = new CookieContainer();
        var collection = JsonConvert.DeserializeObject<CookieCollection>(GetJson());
        collection.Add(new Cookie("c5", "v5", "/", "httpbin.org"));
        cookie.Add(collection);
        var http = new HttpClient(new HttpClientHandler
        {
            UseCookies = true,
            CookieContainer = cookie
        });
        var ret = await http.GetStringAsync("https://httpbin.org/cookies");
        Console.WriteLine(ret);
    

    发现只有后面手动添加的 c5 被正确输出了:

    {
          "cookies": {
            "c5": "v5"
          }
    }
    

    该问题的发生原因笔者并未深究,从 LINQPad 的 Dump 输出上看应该不是公共属性差异造成的:

    ![](https://cdn.coderbusy.com/wp-content/uploads/2021/11/fcff2a91b9f5d5b.png)

    一个简单的解决方案是引入一个自定义的 CookieInfo 对象:

        public class CookieInfo
        {
            public CookieInfo()
            {
    
            }
            public CookieInfo(Cookie cookie)
            {
                this.Name = cookie.Name;
                this.Value = cookie.Value;
                this.Path = cookie.Path;
                this.Domain = cookie.Domain;
            }
            public string Name { get; set; }
            public string Value { get; set; }
            public string Path { get; set; }
            public string Domain { get; set; }
            public Cookie ToCookie()
            {
                return new Cookie(this.Name, this.Value, this.Path, this.Domain);
            }
        }
    

    在序列化和反序列化时,使用 CookieInfo 替代即可:

        static string GetJson()
        {
            var cookie = new CookieContainer();
            cookie.Add(new Cookie("c1", "v1", "/", "httpbin.org"));
            cookie.Add(new Cookie("c2", "v2", "/", "httpbin.org"));
            cookie.Add(new Cookie("c3", "v3", "/", "httpbin.org"));
            cookie.Add(new Cookie("c4", "v4", "/", "httpbin.org"));
            var collection = cookie.GetAllCookies();
            var json = JsonConvert.SerializeObject(collection.Select(i => new CookieInfo(i)));
            return json;
        }
    
        async Task Main()
        {
            var cookie = new CookieContainer();
            var list = JsonConvert.DeserializeObject<List<CookieInfo>>(GetJson());
            var collection = new CookieCollection();
            foreach (var item in list)
            {
                collection.Add(item.ToCookie());
            }
            collection.Add(new Cookie("c5", "v5", "/", "httpbin.org"));
            cookie.Add(collection);
            var http = new HttpClient(new HttpClientHandler
            {
                UseCookies = true,
                CookieContainer = cookie
            });
            var str = await http.GetStringAsync("https://httpbin.org/cookies");
            Console.WriteLine(str);
        }
    

    原文链接:在 .NET 开发中请不要序列化 CookieCollection 和 Cookie 对象

    欢迎来到:码农很忙
  • 相关阅读:
    BS文件夹上传操作(一)
    ext.net 开发学习— 2012 上半年 总结
    C#泛型泛型方法
    C#泛型泛型类
    文件读取,保存操作
    itools下载链接被360警告:虚假招聘网站
    读书推荐:《wordpresss博客建站与经营》
    Net CF简单介绍
    木杉大话微软手机系统
    wp7和wp8的区别
  • 原文地址:https://www.cnblogs.com/Soar1991/p/15579592.html
Copyright © 2011-2022 走看看