自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

對(duì) JsonConvert 的認(rèn)識(shí)太膚淺了,終于還是遇到了問(wèn)題

開發(fā) 前端
雖然阻擊了幾個(gè)回合,但同時(shí)也發(fā)現(xiàn)了 Newtonsoft? 中還有特別多的未挖掘功能,真的需要好好研究研究,源碼已下好,接下來(lái)準(zhǔn)備做個(gè)系列來(lái)解剖一下,值得一提的是 .Net?中已自帶了 System.Text.Json.JsonSerializer 類,目前來(lái)看功能還不算太豐富,簡(jiǎn)單用用還是可以的,本篇就說(shuō)到這里,希望對(duì)您有幫助。

一:背景

1. 講故事

在開始本文之前,真的好想做個(gè)問(wèn)卷調(diào)查,到底有多少人和我一樣,對(duì) JsonConvert 的認(rèn)識(shí)只局限在 SerializeObject 和 DeserializeObject 這兩個(gè)方法上(┬_┬), 這樣我也好結(jié)伴同行,不再孤單落魄??????,或許是這兩個(gè)方法基本上能夠解決工作中 80% 的場(chǎng)景,對(duì)于我來(lái)說(shuō)確實(shí)是這樣,但隨著編碼的延續(xù),終究還是會(huì)遇到那剩下的 20% ,所以呀。。。

我的場(chǎng)景是這樣的:前段時(shí)間寫業(yè)務(wù)代碼的時(shí)候,我有一個(gè)自定義的客戶算法類型的Model,這個(gè)Model中有這種算法類型下的客戶群以及Report統(tǒng)計(jì)信息,還用了 HashSet 記錄了該類型下的 CustomerID集合,為了方便講述,我把Model簡(jiǎn)化如下:

class CustomerAlgorithmModel
    {
        public string DisplayName { get; set; }

        public int CustomerType { get; set; }

        public ReprotModel Report { get; set; }

        public HashSet<int> CustomerIDHash { get; set; }
    }

    class ReprotModel
    {
        public int TotalCustomerCount { get; set; }

        public int TotalTradeCount { get; set; }
    }

那有意思的就來(lái)了,我個(gè)人是有記日志的癖好,就想著以后不會(huì)出現(xiàn)死無(wú)對(duì)證的情況,然后就理所當(dāng)然的使用 JsonConvert.SerializeObject, 這一下就出問(wèn)題了,日志送入到了 ElasticSearch ,然后通過(guò) Kibana 查不出來(lái),為啥呢?看完上面的 Model 我想你也猜到了原因,json體太大了哈,好歹 CustomerIDHash 中也有幾十萬(wàn)個(gè)撒,這一下全導(dǎo)出成json了,這 size 還能小嗎?要不我寫段代碼看一看。

static void Main(string[] args)
        {
            var algorithModel = new CustomerAlgorithmModel()
            {
                CustomerType = 1,
                DisplayName = "????",
                Report = new ReprotModel()
                {
                    TotalCustomerCount = 1000,
                    TotalTradeCount = 50
                },
                CustomerIDHash = new HashSet<int>(Enumerable.Range(1, 500000))
            };

            var json = JsonConvert.SerializeObject(algorithModel);

            File.WriteAllText("1.txt", json, Encoding.UTF8);

            Console.WriteLine("寫入完成!");
        }

圖片圖片

可以看到,僅一個(gè)json就 3.3M,這樣的記錄多來(lái)幾打后,在 kibana 上一檢索,瀏覽器就卡的要死,其實(shí) CustomerIDHash 這個(gè)字段對(duì)我來(lái)說(shuō)是可有可無(wú)的,就算存下來(lái)了也沒(méi)啥大用,所以需求就來(lái)了,如何屏蔽掉 CustomerIDHash。

二:尋求解決方案

1. 使用 JsonIgnore

有問(wèn)題就網(wǎng)上搜啊,這一搜馬上就有人告訴你可以使用 JsonIgnoreAttribute 忽略特性,加好這個(gè)特性后繼續(xù)跑一下程序。

[Newtonsoft.Json.JsonIgnore]
    public HashSet<int> CustomerIDHash { get; set; }

圖片圖片

太好了,終于搞定了,但是靜下心來(lái)想一想,總感覺心里有那么一點(diǎn)不舒服,為什么這么說(shuō),一旦你給這個(gè) CustomerIDHash 套上了 JsonIgnore ,這就意味著它在 JsonConvet 的世界中從此消失,也不管是誰(shuí)在使用這個(gè)Model, 但這并不是我的初衷,我的初衷僅僅是為了在記錄日志的時(shí)候踢掉 CustomerIDHash,可千萬(wàn)不要影響在其他場(chǎng)景下的使用哈,現(xiàn)在這種做法就會(huì)給自己,給別人挖坑,埋下了不可預(yù)知的bug,我想你應(yīng)該明白我的意思,還得繼續(xù)尋找下一個(gè)方案。

2. 使用自定義的 JsonConverter

真的,Newtonsoft 太強(qiáng)大了,我都想寫一個(gè)專題好好彌補(bǔ)彌補(bǔ)我的知識(shí)盲區(qū),其實(shí)在這個(gè)場(chǎng)景中不就是想把 HashSet<int> 給屏蔽掉嘛,Newtonsoft 中專門提供了一個(gè)針對(duì)特定類型的自定義處理類,接下來(lái)我就寫一段:

/// <summary>
    /// 自定義一個(gè) 針對(duì) HashSet<int> 的轉(zhuǎn)換類
    /// </summary>
    public class HashSetConverter : Newtonsoft.Json.JsonConverter<HashSet<int>>
    {
        public override HashSet<int> ReadJson(JsonReader reader, Type objectType, HashSet<int> existingValue, bool hasExistingValue, JsonSerializer serializer)
        {
            return existingValue;
        }

        public override void WriteJson(JsonWriter writer, HashSet<int> value, JsonSerializer serializer)
        {
            writer.WriteNull();
        }
    }

就是這么簡(jiǎn)單,然后就可以在 SerializeObject 的時(shí)候指定下自定義的 HashSetConverter 即可,然后再將程序跑起來(lái)看一下。

var json = JsonConvert.SerializeObject(algorithModel, Formatting.Indented, new HashSetConverter());

圖片圖片

從圖中看,貌似也是解決了,但我突然發(fā)現(xiàn)自己要鉆牛角尖了,如果我的實(shí)體中又來(lái)了一個(gè)頂級(jí)優(yōu)質(zhì)客戶群的 TopNCustomerIDHash,但因?yàn)檫@個(gè)CustomerID 比較少,我希望在 Json 中能保留下來(lái),然后就是踢掉的那個(gè) CustomerIDHash 我要保留 CustomerIDHash.Length,哈哈,搞事情哈,那接下來(lái)怎么解決呢?

  • 修改 Model 實(shí)體
class CustomerAlgorithmModel
    {
        public HashSet<int> CustomerIDHash { get; set; }

        // topN 優(yōu)質(zhì)客戶群
        public HashSet<int> TopNCustomerIDHash { get; set; }
    }
  • HashSetConverter 增加邏輯鑒別是否為保留字段
public override void WriteJson(JsonWriter writer, HashSet<int> value, JsonSerializer serializer)
        {
            if (writer.Path == "TopNCustomerIDHash")
            {
                writer.WriteStartArray();

                foreach (var item in value)
                {
                    writer.WriteValue(item);
                }

                writer.WriteEndArray();
            }
            else
            {
                writer.WriteValue(value.Count);
            }
        }
  • 最后給 TopNCustomerIDHash 賦值
var algorithModel = new CustomerAlgorithmModel()
            {
                CustomerType = 1,
                DisplayName = "????",
                Report = new ReprotModel()
                {
                    TotalCustomerCount = 1000,
                    TotalTradeCount = 50
                },
                CustomerIDHash = new HashSet<int>(Enumerable.Range(1, 500000)),
                TopNCustomerIDHash = new HashSet<int>(Enumerable.Range(1, 10)),
            };

三塊都搞定后就可以把程序跑起來(lái)了,如下圖:

圖片圖片

貌似鉆牛角尖的問(wèn)題是解決了,既然鉆牛角尖肯定要各種鄙視,比如這里的 ReportModel 我是不需要的,CustomerType 我也是不需要的,我僅僅需要看一下 DisplayName 和 TotalCustomerCount 這兩個(gè)字段就可以了, 那這個(gè)要怎么解決呢?

3. 使用 匿名類型

確實(shí)很多時(shí)候記日志,就是為了跟蹤 Model 中你特別關(guān)心的那幾個(gè)字段,所以摻雜了多余的字段確實(shí)也是沒(méi)必要的,這里可以用匿名來(lái)解決,我就來(lái)寫一段代碼:

var json = JsonConvert.SerializeObject(new
    {
        algorithModel.DisplayName,
        algorithModel.Report.TotalCustomerCount
    }, Formatting.Indented);

圖片圖片

三:總結(jié)

雖然阻擊了幾個(gè)回合,但同時(shí)也發(fā)現(xiàn)了 Newtonsoft 中還有特別多的未挖掘功能,真的需要好好研究研究,源碼已下好,接下來(lái)準(zhǔn)備做個(gè)系列來(lái)解剖一下,值得一提的是 .Net中已自帶了 System.Text.Json.JsonSerializer 類,目前來(lái)看功能還不算太豐富,簡(jiǎn)單用用還是可以的,本篇就說(shuō)到這里,希望對(duì)您有幫助。

責(zé)任編輯:武曉燕 來(lái)源: 一線碼農(nóng)聊技術(shù)
相關(guān)推薦

2024-10-10 12:34:44

2022-09-04 19:15:02

運(yùn)維技術(shù)

2021-10-26 08:22:38

消息堆積擴(kuò)容RocketMQ

2020-02-23 16:33:02

GitHub印度子公司

2023-03-02 06:00:00

2023-11-02 08:43:08

protocgo兼容

2017-10-24 12:32:03

小程序APPbug

2024-12-17 10:07:13

死鎖數(shù)據(jù)庫(kù)日志

2018-12-26 09:03:30

物聯(lián)網(wǎng)IOT智能

2021-03-08 08:16:30

負(fù)載均衡系統(tǒng)流量

2020-08-12 15:29:33

蘋果iPhone微信

2010-08-17 13:47:09

DB2還原

2021-09-15 09:31:39

前端開發(fā)工具

2013-07-26 09:16:13

SwiftOpenStackSwiftStack

2022-05-24 16:09:38

前端腳本

2021-03-05 14:40:49

Chrome瀏覽器內(nèi)存

2024-01-24 09:02:45

React版本Next.js

2019-06-17 08:30:09

TCPIP通信協(xié)議

2013-09-24 14:57:10

2020-04-24 20:05:16

VueAxios前端
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)