第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

Newtonsoft.Json - 反序列化不帶引號(hào)的大寫布爾值

Newtonsoft.Json - 反序列化不帶引號(hào)的大寫布爾值

C#
開心每一天1111 2023-09-16 20:03:38
我從 API 收到一些不太符合 ISO 標(biāo)準(zhǔn)的 Json 內(nèi)容。布爾值為大寫而不是小寫。{ "Bool": False }最初,我認(rèn)為通過使用自定義應(yīng)該很容易解決,例如如何讓 newtonsoft 將 yes 和 no 反序列化為布爾值。JsonConverter但看起來該方法從未被調(diào)用過。我認(rèn)為原因是,該值不在引號(hào)中,因此永遠(yuǎn)不會(huì)調(diào)用轉(zhuǎn)換器并創(chuàng)建異常。JsonConverter.ReadJsonFalseJsonTextReader處理這種情況的最佳方法是什么?public class BoolTests{    public class A    {        [JsonConverter(typeof(CaseIgnoringBooleanConverter))]        public bool Bool { get; set; }    }    [Theory]    [InlineData(false, "{'Bool': false}")] //ok    [InlineData(false, "{'Bool': 'False'}")] // ok    [InlineData(false, "{'Bool': False")] // fails    public void CasingMatters(bool expected, string json)    {        var actual = JsonConvert.DeserializeObject<A>(json);        Assert.Equal(expected, actual.Bool);    }}// taken from https://gist.github.com/randyburden/5924981public class CaseIgnoringBooleanConverter : JsonConverter{    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)    {        switch (reader.Value.ToString().ToUpperInvariant().Trim())        {            case "TRUE":                return true;            case "FALSE":                return false;        }        // If we reach here, we're pretty much going to throw an error so let's let Json.NET throw it's pretty-fied error message.        return new JsonSerializer().Deserialize(reader, objectType);    }    public override bool CanConvert(Type objectType)    {        return objectType == typeof(bool);    }    public override bool CanWrite => false;    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)    {        throw new NotImplementedException();    }}
查看完整描述

2 回答

?
30秒到達(dá)戰(zhàn)場(chǎng)

TA貢獻(xiàn)1828條經(jīng)驗(yàn) 獲得超6個(gè)贊

不幸的是,正如您所發(fā)現(xiàn)的,無效的 json 是無效的,因此無法由普通和常見的 json (de) 序列化程序(如 Json.net)處理。

對(duì)反序列化程序使用轉(zhuǎn)換器和策略設(shè)置也不起作用,因?yàn)樗鼈冎荚谔幚碇T如空對(duì)象作為數(shù)組返回或名稱轉(zhuǎn)換/大小寫處理之類的事情。

一個(gè)天真的解決方案是做一個(gè)簡(jiǎn)單的字符串替換,比如

string?json?=?invalidJson.Replace("False",?"false");

但是,這存在一些問題:

  1. 您需要將整個(gè)無效的 json 讀入內(nèi)存,并創(chuàng)建它的固定副本,這意味著您將在內(nèi)存中擁有兩個(gè)完整的數(shù)據(jù)副本,一個(gè)是壞的,一個(gè)是好的。

  2. 它也會(huì)替換內(nèi)部字符串。這可能不是您的數(shù)據(jù)問題,但使用上述方法并不容易處理。False

另一種方法是編寫一個(gè)基本的分詞器,該分詞器可以理解基本的 JSON 語法,例如字符串、數(shù)字和標(biāo)識(shí)符,并逐個(gè)令牌遍歷文件,替換錯(cuò)誤的標(biāo)識(shí)符。這將解決問題 2,但根據(jù)解決方案,可能需要更復(fù)雜的實(shí)現(xiàn)來修復(fù)內(nèi)存問題 1。

下面發(fā)布了一個(gè)簡(jiǎn)單的嘗試,創(chuàng)建一個(gè)可以使用的標(biāo)識(shí)符,這將在找到標(biāo)識(shí)符時(shí)修復(fù)它們,否則可以理解基本的 JSON 令牌。TextReader

請(qǐng)注意以下幾點(diǎn):

  1. 它不是真正的性能。它始終分配臨時(shí)緩沖區(qū)。您可能希望研究“緩沖區(qū)租用”以更好地處理此方法,甚至只是直接流式傳輸?shù)骄彌_區(qū)。

  2. 它不處理數(shù)字,因?yàn)槟菚r(shí)我停止編寫代碼。我把這個(gè)留作練習(xí)??梢跃帉懟镜臄?shù)字處理,因?yàn)槟]有真正驗(yàn)證文件是否具有有效的 JSON,因此可以添加任何可以獲取足夠字符來構(gòu)成數(shù)字的內(nèi)容。

  3. 我沒有用非常大的文件對(duì)此進(jìn)行測(cè)試,只用小的示例文件進(jìn)行測(cè)試。我復(fù)制了一個(gè)9.5MB的文本,它適用于此。List<Test>

  4. 我沒有測(cè)試所有 JSON 語法??赡艽嬖趹?yīng)該處理但未處理的字符。如果您最終使用它,請(qǐng)創(chuàng)建大量測(cè)試!

但是,它的作用是根據(jù)您發(fā)布的標(biāo)識(shí)符修復(fù)無效的 JSON,并且它以流式方式執(zhí)行此操作。因此,無論您的 JSON 文件有多大,這都應(yīng)該可用。

無論如何,這是代碼,再次注意有關(guān)數(shù)字的異常:

void Main()

{

? ? using (var file = File.OpenText(@"d:\temp\test.json"))

? ? using (var fix = new MyFalseFixingTextReader(file))

? ? {

? ? ? ? var reader = new JsonTextReader(fix);

? ? ? ? var serializer = new JsonSerializer();

? ? ? ? serializer.Deserialize<Test>(reader).Dump();

? ? }

}


public class MyFalseFixingTextReader : TextReader

{

? ? private readonly TextReader _Reader;

? ? private readonly StringBuilder _Buffer = new StringBuilder(32768);


? ? public MyFalseFixingTextReader(TextReader reader) => _Reader = reader;


? ? public override void Close()

? ? {

? ? ? ? _Reader.Close();

? ? ? ? base.Close();

? ? }


? ? public override int Read(char[] buffer, int index, int count)

? ? {

? ? ? ? TryFillBuffer(count);


? ? ? ? int amountToCopy = Math.Min(_Buffer.Length, count);

? ? ? ? _Buffer.CopyTo(0, buffer, index, amountToCopy);

? ? ? ? _Buffer.Remove(0, amountToCopy);

? ? ? ? return amountToCopy;

? ? }


? ? private (bool more, char c) TryReadChar()

? ? {

? ? ? ? int i = _Reader.Read();

? ? ? ? if (i < 0)

? ? ? ? ? ? return (false, default);

? ? ? ? return (true, (char)i);

? ? }


? ? private (bool more, char c) TryPeekChar()

? ? {

? ? ? ? int i = _Reader.Peek();

? ? ? ? if (i < 0)

? ? ? ? ? ? return (false, default);

? ? ? ? return (true, (char)i);

? ? }


? ? private void TryFillBuffer(int count)

? ? {

? ? ? ? if (_Buffer.Length >= count)

? ? ? ? ? ? return;


? ? ? ? while (_Buffer.Length < count)

? ? ? ? {

? ? ? ? ? ? var (more, c) = TryPeekChar();

? ? ? ? ? ? if (!more)

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? switch (c)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? case '{':

? ? ? ? ? ? ? ? case '}':

? ? ? ? ? ? ? ? case '[':

? ? ? ? ? ? ? ? case ']':

? ? ? ? ? ? ? ? case '\r':

? ? ? ? ? ? ? ? case '\n':

? ? ? ? ? ? ? ? case ' ':

? ? ? ? ? ? ? ? case '\t':

? ? ? ? ? ? ? ? case ':':

? ? ? ? ? ? ? ? case ',':

? ? ? ? ? ? ? ? ? ? _Reader.Read();

? ? ? ? ? ? ? ? ? ? _Buffer.Append(c);

? ? ? ? ? ? ? ? ? ? break;


? ? ? ? ? ? ? ? case '"':

? ? ? ? ? ? ? ? ? ? _Buffer.Append(GrabString());

? ? ? ? ? ? ? ? ? ? break;


? ? ? ? ? ? ? ? case char letter when char.IsLetter(letter):

? ? ? ? ? ? ? ? ? ? var identifier = GrabIdentifier();

? ? ? ? ? ? ? ? ? ? _Buffer.Append(ReplaceFaultyIdentifiers(identifier));

? ? ? ? ? ? ? ? ? ? break;


? ? ? ? ? ? ? ? case char startOfNumber when startOfNumber == '-' || (startOfNumber >= '0' && startOfNumber <= '9'):

? ? ? ? ? ? ? ? ? ? _Buffer.Append(GrabNumber());

? ? ? ? ? ? ? ? ? ? break;


? ? ? ? ? ? ? ? default:

? ? ? ? ? ? ? ? ? ? throw new InvalidOperationException($"Unable to cope with character '{c}' (0x{((int)c).ToString("x2")})");

? ? ? ? ? ? }

? ? ? ? }

? ? }


? ? private string ReplaceFaultyIdentifiers(string identifier)

? ? {

? ? ? ? switch (identifier)

? ? ? ? {

? ? ? ? ? ? case "False":

? ? ? ? ? ? ? ? return "false";


? ? ? ? ? ? case "True":

? ? ? ? ? ? ? ? return "true";


? ? ? ? ? ? case "Null":

? ? ? ? ? ? ? ? return "null";


? ? ? ? ? ? default:

? ? ? ? ? ? ? ? return identifier;

? ? ? ? }

? ? }


? ? private string GrabNumber()

? ? {

? ? ? ? throw new NotImplementedException("Left as an excercise");

? ? ? ? // See https://www.json.org/ for the syntax

? ? }


? ? private string GrabIdentifier()

? ? {

? ? ? ? var result = new StringBuilder();

? ? ? ? while (true)

? ? ? ? {

? ? ? ? ? ? int i = _Reader.Peek();

? ? ? ? ? ? if (i < 0)

? ? ? ? ? ? ? ? break;


? ? ? ? ? ? char c = (char)i;

? ? ? ? ? ? if (char.IsLetter(c))

? ? ? ? ? ? {

? ? ? ? ? ? ? ? _Reader.Read();

? ? ? ? ? ? ? ? result.Append(c);

? ? ? ? ? ? }

? ? ? ? ? ? else

? ? ? ? ? ? ? ? break;

? ? ? ? }

? ? ? ? return result.ToString();

? ? }


? ? private string GrabString()

? ? {

? ? ? ? _Reader.Read();


? ? ? ? var result = new StringBuilder();

? ? ? ? result.Append('"');


? ? ? ? while (true)

? ? ? ? {

? ? ? ? ? ? var (more, c) = TryReadChar();

? ? ? ? ? ? if (!more)

? ? ? ? ? ? ? ? return result.ToString();


? ? ? ? ? ? switch (c)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? case '"':

? ? ? ? ? ? ? ? ? ? result.Append(c);

? ? ? ? ? ? ? ? ? ? return result.ToString();


? ? ? ? ? ? ? ? case '\\':

? ? ? ? ? ? ? ? ? ? result.Append(c);

? ? ? ? ? ? ? ? ? ? (more, c) = TryReadChar();

? ? ? ? ? ? ? ? ? ? if (!more)

? ? ? ? ? ? ? ? ? ? ? ? return result.ToString();


? ? ? ? ? ? ? ? ? ? switch (c)

? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? case 'u':

? ? ? ? ? ? ? ? ? ? ? ? ? ? result.Append(c);

? ? ? ? ? ? ? ? ? ? ? ? ? ? for (int index = 1; index <= 4; index++)

? ? ? ? ? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (more, c) = TryReadChar();

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (!more)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return result.ToString();

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? result.Append(c);

? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? ? ? break;


? ? ? ? ? ? ? ? ? ? ? ? default:

? ? ? ? ? ? ? ? ? ? ? ? ? ? result.Append(c);

? ? ? ? ? ? ? ? ? ? ? ? ? ? break;

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? break;


? ? ? ? ? ? ? ? default:

? ? ? ? ? ? ? ? ? ? result.Append(c);

? ? ? ? ? ? ? ? ? ? break;

? ? ? ? ? ? }

? ? ? ? }

? ? }

}


public class Test

{

? ? public bool False1 { get; set; }

? ? public bool False2 { get; set; }

? ? public bool False3 { get; set; }

}

示例文件:


{

? ? "false1": false,

? ? "false2": "false",

? ? "false3": False

}

輸出:

https://img1.sycdn.imooc.com/650599f60001190c00990093.jpg

查看完整回答
反對(duì) 回復(fù) 2023-09-16
?
藍(lán)山帝景

TA貢獻(xiàn)1843條經(jīng)驗(yàn) 獲得超7個(gè)贊

應(yīng)在源中修復(fù)無效的 json。


如果你真的需要按原樣解析它,如果你想把它作為一個(gè)字符串,你可以用“False”替換 False,如果你想把它作為一個(gè)布爾值,你可以用 false 替換它。


// If you want a string

json.Replace("False", "\"False\"");


// If you want a bool

json.Replace("False", "false");

一個(gè)問題是,如果一個(gè)鍵或其他值包含“False”模式。


查看完整回答
反對(duì) 回復(fù) 2023-09-16
  • 2 回答
  • 0 關(guān)注
  • 257 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)