Runtime: ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° "динамичСской" ΠΈ доступной для записи ΠΌΠΎΠ΄Π΅Π»ΠΈ DOM.

Π‘ΠΎΠ·Π΄Π°Π½Π½Ρ‹ΠΉ Π½Π° 29 мая 2019  Β·  47ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ  Β·  Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: dotnet/runtime

ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ Π»ΠΈ JsonSerializer.Parse(String, Type, JsonSerializerOptions) динамичСский Ρ‚ΠΈΠΏ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π° ExpandoObject ?

Π§Ρ‚ΠΎ-Ρ‚ΠΎ Π²Ρ€ΠΎΠ΄Π΅ этого:
dynamic p = JsonSerializer.Parse(json, typeof(ExpandoObject));

area-System.Text.Json enhancement json-functionality-doc

Π‘Π°ΠΌΡ‹ΠΉ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹ΠΉ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ

Π£ мСня Ρ‚Π°ΠΊΠΆΠ΅ Π΅ΡΡ‚ΡŒ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ использования для этого - я просто Ρ…ΠΎΡ‡Ρƒ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ REST API с HttpClient ΠΈ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΎΠ΄Π½ΠΎ свойство ΠΈΠ· ΠΎΡ‚Π²Π΅Ρ‚Π°. Π― Π½Π΅ Ρ…ΠΎΡ‡Ρƒ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΉ класс Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для Π°Π½Π°Π»ΠΈΠ·Π° ΠΎΡ‚Π²Π΅Ρ‚Π° ... Π‘ JSON.NET я ΠΌΠΎΠ³ Π±Ρ‹ просто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ «динамичСский» ΠΈ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ доступ ΠΊ Π²Ρ‹Π±Ρ€Π°Π½Π½ΠΎΠΌΡƒ свойству.

ВсС 47 ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ

НСт, эта функция Π½Π° Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π½Π΅ поддСрТиваСтся, Π½ΠΎ ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡƒΡ‡Π΅ΡΡ‚ΡŒ это Π² vNext. Π£ вас Π΅ΡΡ‚ΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ использования, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΌΠΎΡ‚ΠΈΠ²ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ запрос Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ?

ΠžΡ‚ΠΌΠ΅Ρ‡Π΅Π½ΠΎ ΠΊΠ°ΠΊ Π±ΡƒΠ΄ΡƒΡ‰Π΅Π΅.

System.NotSupportedException : The collection type 'System.Dynamic.ExpandoObject' is not supported.

@ahsonkhan GraphQL - Ρ…ΠΎΡ€ΠΎΡˆΠΈΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€.

Π’ спСцификации рСкомСндуСтся JSON, Π½ΠΎ ΠΎΠ½ Π½Π΅ привязан ΠΊ ΠΊΠ°ΠΊΠΎΠΉ-Π»ΠΈΠ±ΠΎ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΉ сСриализации Π² ΠΎΡ‚Π²Π΅Ρ‚Π΅.
Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ»Π΅ Β«Π΄Π°Π½Π½Ρ‹Π΅Β» ΠΎΡ‚Π²Π΅Ρ‚Π° ΠΈΠΌΠ΅Π΅Ρ‚ Π²ΠΈΠ΄: динамичСскоС. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ это Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΡ‚ΡŒ.
Π‘Π΅Π· ExpandoObject дСсСриализация Π΄Π΅Π»Π°Π΅Ρ‚ динамичСский Ρ‚ΠΈΠΏ создания JSON. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, доступ ΠΊ этим абстрактным динамичСским Β«Π΄Π°Π½Π½Ρ‹ΠΌΒ» Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΎΡΡƒΡ‰Π΅ΡΡ‚Π²Π»ΡΡ‚ΡŒΡΡ с ΡƒΡ‡Π΅Ρ‚ΠΎΠΌ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ Π½Π° самом Π΄Π΅Π»Π΅ эти динамичСскиС Π΄Π°Π½Π½Ρ‹Π΅ ΡΠ²Π»ΡΡŽΡ‚ΡΡ JToken.

Π― Π΄ΡƒΠΌΠ°ΡŽ, Ρ‡Ρ‚ΠΎ с ExpandoObject ΠΌΡ‹ ΠΌΠΎΠ³Π»ΠΈ Π±Ρ‹ ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΡ‚ΡŒ доступ ΠΊ динамичСским Β«Π΄Π°Π½Π½Ρ‹ΠΌΒ» ΠΊΠ°ΠΊ ΠΊ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠΌΡƒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ.

@ahsonkhan Π΅Ρ‰Π΅ ΠΎΠ΄ΠΈΠ½ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ - слуТба ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ Π² нашСм ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅. Он прСдоставляСт ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΡŽ, Ρ‚Π°ΠΊΡƒΡŽ ​​как ΠΊΠΎΠ½Π΅Ρ‡Π½Ρ‹Π΅ Ρ‚ΠΎΡ‡ΠΊΠΈ REST, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡΠΎΠ·Π΄Π°ΡŽΡ‚ ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΠΈ Π² MongoDB (это Π½Π΅ просто фиктивная ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠ° REST, Π° ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΠΈ ΠΈ коллСкция mongo Π½Π΅ ΠΈΠΌΠ΅ΡŽΡ‚ Ρ‚ΠΎΡ‡Π½ΠΎΠ³ΠΎ сопоставлСния 1-1, ΠΎΠ½Π° Ρ‚Π°ΠΊΠΆΠ΅ ΡƒΡ‚Π²Π΅Ρ€ΠΆΠ΄Π°Π΅Ρ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Π΅ ΠΏΡ€Π°Π²ΠΈΠ»Π°).

Π’Π°ΠΊ Ρ‡Ρ‚ΠΎ Π² нашСм ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅ Π½Π°ΠΌ Π½ΡƒΠΆΠ½Π° динамичСская ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° / ExpandoObject.

ΠœΡ‹ Ρ‚Π°ΠΊΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Π΅Π³ΠΎ Π² Π΄Ρ€ΡƒΠ³ΠΈΡ… микросСрвисах.

ΠœΡ‹ Ρ‚ΠΎΠΆΠ΅ ΡΡ‚ΠΎΠ»ΠΊΠ½ΡƒΠ»ΠΈΡΡŒ с этим ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ΠΌ. Наш Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ использования - это постСпСнноС созданиС динамичСского ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΏΠ΅Ρ€Π΅Π΄ сСриализациСй json. ВСрнулся ΠΊ Π±ΠΎΠ»Π΅Π΅ Π·Ρ€Π΅Π»ΠΎΠΌΡƒ сСриализатору Json.NET.

ΠŸΡ€ΠΈΠ²Π΅Ρ‚, рСбята

какая ΠΏΡ€ΠΎΠ³ΡƒΠ»ΠΊΠ° сСйчас?
ΠœΠΎΠ³Ρƒ Π»ΠΈ я Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ, ΠΊΠ°ΠΊΠΎΠΉ ΠΈΠ· Π½ΠΈΡ… ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ?
@SidShetye, Ρ‚Ρ‹ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ сказал, вСрнулся ΠΊ Π±ΠΎΠ»Π΅Π΅ Π·Ρ€Π΅Π»ΠΎΠΌΡƒ, Π½Π΅ ΠΌΠΎΠ³Π»ΠΈ Π±Ρ‹ Π²Ρ‹ ΠΎΠ±ΡŠΡΡΠ½ΠΈΡ‚ΡŒ, поТалуйста?

@MickeyReznikov : см. Https://stackoverflow.com/questions/15455304/deserialize-a-property-as-an-expandoobject-using-json-net или google «json.net expandoobject»

@MickeyReznikov , ΠΎΡ‚Π²Π΅Ρ‚ΠΈΠ»ΠΈ Π½Π° ваш вопрос? Π― ΡΡ‡ΠΈΡ‚Π°ΡŽ, Ρ‡Ρ‚ΠΎ @SidShetye ΠΎΠ·Π½Π°Ρ‡Π°Π»ΠΎ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒΡΡ ΠΊ использованию Newtonsoft.Json для сСриализации динамичСских ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ встроСнная Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° (System.Text.Json) Π΅Ρ‰Π΅ Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ ΠΈΡ…. Π’ случаС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ asp.net Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ Π΅Π³ΠΎ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ Π½Π° AddNewtonsoftJson.

Π‘ΠΌ. Https://docs.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-3.0&tabs=visual-studio#jsonnet -support

Π£ мСня Ρ‚Π°ΠΊΠΆΠ΅ Π΅ΡΡ‚ΡŒ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ использования для этого - я просто Ρ…ΠΎΡ‡Ρƒ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ REST API с HttpClient ΠΈ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΎΠ΄Π½ΠΎ свойство ΠΈΠ· ΠΎΡ‚Π²Π΅Ρ‚Π°. Π― Π½Π΅ Ρ…ΠΎΡ‡Ρƒ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΉ класс Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для Π°Π½Π°Π»ΠΈΠ·Π° ΠΎΡ‚Π²Π΅Ρ‚Π° ... Π‘ JSON.NET я ΠΌΠΎΠ³ Π±Ρ‹ просто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ «динамичСский» ΠΈ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ доступ ΠΊ Π²Ρ‹Π±Ρ€Π°Π½Π½ΠΎΠΌΡƒ свойству.

Π‘ https://github.com/dotnet/corefx/issues/41472 ΠΎΡ‚ @ ghost1372 :

ΠΏΡ€ΠΈΠ²Π΅Ρ‚, я надСюсь, это Ρ…ΠΎΡ€ΠΎΡˆΠ΅Π΅ мСсто, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π·Π°Π΄Π°Ρ‚ΡŒ этот вопрос
ΠšΠ°ΠΆΠ΅Ρ‚ΡΡ, ΠΌΡ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π΅ΡΠ΅Ρ€ΠΈΠ°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ динамичСскиС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹
Π― использовал этот ΠΊΠΎΠ΄, Π½ΠΎ Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Π», Π΅ΡΡ‚ΡŒ Π»ΠΈ способ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ это?

var objList = System.Text.Json.JsonSerializer.Deserialize<List<dynamic>>(json);

Π’ΠΎ ΠΌΠ½ΠΎΠ³ΠΈΡ… Π½Π°ΡˆΠΈΡ… прилоТСниях ΠΌΡ‹ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€ΡƒΠ΅ΠΌ поля Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ· Ρ…Ρ€Π°Π½ΠΈΠΌΡ‹Ρ… ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€ ΠΈ динамичСски ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅ΠΌ страницы списка ΠΈ списка поиска с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ jquery.jtable.

Π‘Π΅Π· встроСнной ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ JsonSerializer для ExpandoObject ΠΌΡ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π²ΡΡ‚Ρ€ΠΎΠ΅Π½Π½ΡƒΡŽ ΡΠ΅Ρ€ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ Json Π² ядрС dotnet.

ΠœΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Ρ‚ΠΎΡ‚ ΠΆΠ΅ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ использования, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΡƒΠΆΠ΅ упоминался @estiller ΠΈ @SidShetye.
Π’Π΅ΠΌ Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ Π½Π°ΠΌ ΠΏΡ€ΠΈΡˆΠ»ΠΎΡΡŒ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒΡΡ Π½Π° Json.NET.

Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π»ΠΈ ΠΈΠΌΠ΅Ρ‚ΡŒ Π²Π΅Ρ…Ρƒ Π±Π»ΠΈΠΆΠ΅ ΠΊ _ сСйчас_, Ρ‡Π΅ΠΌ ΠΊ Π±ΡƒΠ΄ΡƒΡ‰Π΅ΠΌΡƒ ? πŸ€”

ExpandoObject Π±Ρ‹Π» Π² BCL Π² Ρ‚Π΅Ρ‡Π΅Π½ΠΈΠ΅ Π΄ΠΎΠ»Π³ΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ

Π•ΡΡ‚ΡŒ Π»ΠΈ Π°Π»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Π° ExpandoObject?

@fatihyildizhan НСт Π°Π»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Ρ‹.

Π½ΠΎ ΠΌΡ‹ написали наш собствСнный ΠΊΠΎΠ½Π²Π΅Ρ€Ρ‚Π΅Ρ€ ExpandoObject, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ подсказкой ΠΈΠ· этой ΡΡ‚Π°Ρ‚ΡŒΠΈ ASP.NET Core 3.0: Custom JsonConverter для Π½ΠΎΠ²ΠΎΠ³ΠΎ System.Text.Json

Нам Π½ΡƒΠΆΠ½Π° Ρ‚ΠΎΠ»ΡŒΠΊΠΎ сСриализация, поэтому ΠΌΡ‹ просто создаСм ΡΠ΅Ρ€ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ

Π― Π±Ρ‹Π» ΡƒΠ΄ΠΈΠ²Π»Π΅Π½, Ρ‡Ρ‚ΠΎ это Π΅Ρ‰Π΅ Π½Π΅ поддСрТиваСтся.

ΠŸΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ Π½Π° 5.0.

ΠŸΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΡ‚Π΅ Π½Π° 5.0? Π—Π½Π°Ρ‡ΠΈΡ‚, Π½Π°Π΄ΠΎ ΠΆΠ΄Π°Ρ‚ΡŒ ΠΌΠΈΠ½ΠΈΠΌΡƒΠΌ Π³ΠΎΠ΄? ВСрнСмся ΠΊ JSON.Net.

5.0? Π²Π°Ρƒ, это ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎ отстой.

Для Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠ³ΠΎ ΡƒΡ€ΠΎΠ΄Π»ΠΈΠ²ΠΎΠ³ΠΎ ΠΎΠ±Ρ…ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΡƒΡ‚ΠΈ я ΠΌΠΎΠ³Ρƒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ JsonDocument с настраиваСмым ΠΊΠΎΠ½Π²Π΅Ρ€Ρ‚Π΅Ρ€ΠΎΠΌ для Π½Π΅Π³ΠΎ, Π½ΠΎ это IDisposable.

public sealed class EventObject
    {
        [JsonPropertyName("id")]
        public long Id
        {
            get; set;
        }

        [JsonPropertyName("eventData")]
        [JsonConverter(typeof(JsonDocumentConverter))]
        public System.Text.Json.JsonDocument EventData
        {
            get; set;
        }
    }

    internal sealed class JsonDocumentConverter
        : JsonConverter<System.Text.Json.JsonDocument>
    {
        public override JsonDocument Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            return JsonDocument.ParseValue(ref reader);
        }

        public override void Write(Utf8JsonWriter writer, JsonDocument value, JsonSerializerOptions options)
        {
            value.WriteTo(writer);
        }
    }

ΠœΡ‹ большС Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅ дСйствиС POST Π² присутствии System.Text.Json:

[HttpPost]
public async Task<IActionResult> SubmitAsync(dynamic model)

ВмСсто этого Π½Π°ΠΌ ΠΏΡ€ΠΈΡˆΠ»ΠΎΡΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄, Π½ΠΎ Π½Π΅ Π±Ρ‹Π»ΠΎ прямого использования Β«ΠΌΠΎΠ΄Π΅Π»ΠΈΒ» Π² нисходящСм бэкэнд-ΠΊΠΎΠ΄Π΅:

[HttpPost]
public async Task<IActionResult> SubmitAsync(JsonElement model)

«модСль» - это слоТный ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ Π½Π°Π±ΠΎΡ€ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² ΠΈ / ΠΈΠ»ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΡ… Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Ρ… слоТных ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ². Π§Ρ‚ΠΎΠ±Ρ‹ ΠΈΠΌΠ΅Ρ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Π·Π°ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ dynamic ΠΈΠ· JsonElement , Π½Π°ΠΌ ΠΏΡ€ΠΈΡˆΠ»ΠΎΡΡŒ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ model.GetRawText () ΠΈ Π·Π°ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Newtonsoft Π΄Π΅ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ Π² динамичСский ΠΎΠ±ΡŠΠ΅ΠΊΡ‚. Π­Ρ‚ΠΎ Π½Π΅ΠΆΠ΅Π»Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ способ, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ основной Ρ†Π΅Π»ΡŒΡŽ этого упраТнСния Π±Ρ‹Π»ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Newtonsoft.json ΠΈΠ· ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°.

ΠœΠΎΠ³Ρƒ Π»ΠΈ я ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ ΠΊ этой заявкС / ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ΅ ΠΏΠΎΠ΄Ρ€Π°Π·ΡƒΠΌΠ΅Π²Π°Π΅Ρ‚ исправлСниС нашСй ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹, с ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΌΡ‹ ΡΡ‚ΠΎΠ»ΠΊΠ½ΡƒΠ»ΠΈΡΡŒ? ΠšΠ°ΠΆΠ΅Ρ‚ΡΡ, это Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ срочный вопрос, поэтому ΠΌΠΎΠΆΠ½ΠΎ Π»ΠΈ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ Π΅Π³ΠΎ Ρ€Π°Π½ΡŒΡˆΠ΅, Ρ‡Π΅ΠΌ ΠΏΠΎΠ·ΠΆΠ΅?

/ cc @ahsonkhan @terrajobst

.NET Core 3.0 JsonSerializer.Deserialize Π² динамичСский ΠΎΠ±ΡŠΠ΅ΠΊΡ‚

ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° JsonSerializer для ExpandoObject (Π²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΌΠ΅Ρ€Ρ‹)
Π― Π½ΠΎΠ²ΠΈΡ‡ΠΎΠΊ, ΠΌΠ½ΠΎΠ³ΠΈΠ΅ мСста Π½Π΅ ΠΈΠ΄Π΅Π°Π»ΡŒΠ½Ρ‹, ΠΏΡ€ΠΈΠ³Π»Π°ΡˆΠ°Π΅ΠΌ всСх ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ
.net Core3 Π½Π΅ поддСрТиваСтся

Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΊΠΎΠ½Π²Π΅Ρ€Ρ‚Π΅Ρ€ Json

Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ:

  • using System.Text.Json;
  • using System.Text.Json.Serialization;

`` Π‘ #
///


/// Π’Π΅ΠΌΠΏΠ΅Ρ€Π°Ρ‚ΡƒΡ€Π½Ρ‹ΠΉ динамичСский ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ
/// Π°Π²Ρ‚ΠΎΡ€: [email protected]
///

ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΉ класс DynamicJsonConverter: JsonConverter
{
общСдоступноС ΠΏΠ΅Ρ€Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ динамичСского чтСния (см. Utf8JsonReader reader,
Π’ΠΈΠΏ typeToConvert,
ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ JsonSerializerOptions)
{

        if (reader.TokenType == JsonTokenType.True)
        {
            return true;
        }

        if (reader.TokenType == JsonTokenType.False)
        {
            return false;
        }

        if (reader.TokenType == JsonTokenType.Number)
        {
            if (reader.TryGetInt64(out long l))
            {
                return l;
            }

            return reader.GetDouble();
        }

        if (reader.TokenType == JsonTokenType.String)
        {
            if (reader.TryGetDateTime(out DateTime datetime))
            {
                return datetime;
            }

            return reader.GetString();
        }

        if (reader.TokenType == JsonTokenType.StartObject)
        {
            using JsonDocument documentV = JsonDocument.ParseValue(ref reader);
            return ReadObject(documentV.RootElement);
        }
        // Use JsonElement as fallback.
        // Newtonsoft uses JArray or JObject.
        JsonDocument document = JsonDocument.ParseValue(ref reader);
        return document.RootElement.Clone();
    }

    private object ReadObject(JsonElement jsonElement)
    {
        IDictionary<string, object> expandoObject = new ExpandoObject();
        foreach (var obj in jsonElement.EnumerateObject())
        {
            var k = obj.Name;
            var value = ReadValue(obj.Value);
            expandoObject[k] = value;
        }
        return expandoObject;
    }
    private object? ReadValue(JsonElement jsonElement)
    {
        object? result = null;
        switch (jsonElement.ValueKind)
        {
            case JsonValueKind.Object:
                result = ReadObject(jsonElement);
                break;
            case JsonValueKind.Array:
                result = ReadList(jsonElement);
                break;
            case JsonValueKind.String:
                //TODO: Missing Datetime&Bytes Convert
                result = jsonElement.GetString();
                break;
            case JsonValueKind.Number:
                //TODO: more num type
                result = 0;
                if (jsonElement.TryGetInt64(out long l))
                {
                    result = l;
                }
                break;
            case JsonValueKind.True:
                result = true;
                break;
            case JsonValueKind.False:
                result = false;
                break;
            case JsonValueKind.Undefined:
            case JsonValueKind.Null:
                result = null;
                break;
            default:
                throw new ArgumentOutOfRangeException();
        }
        return result;
    }

    private object? ReadList(JsonElement jsonElement)
    {
        IList<object?> list = new List<object?>();
        foreach (var item in jsonElement.EnumerateArray())
        {
            list.Add(ReadValue(item));
        }
        return list.Count == 0 ? null : list;
    }
    public override void Write(Utf8JsonWriter writer,
        object value,
        JsonSerializerOptions options)
    {
       // writer.WriteStringValue(value.ToString());
    }
}
## How to Use?

```C#
var serializerOptions = new JsonSerializerOptions
{
    Converters = { new DynamicJsonConverter() }
};
return JsonSerializer.Deserialize<dynamic>("{OK:"200"}", serializerOptions);

@tchivs , вашС Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Ρƒ мСня сработало; Π½ΠΎ ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ свойство Converters доступно Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для чтСния, ΠΌΠ½Π΅ ΠΏΡ€ΠΈΡˆΠ»ΠΎΡΡŒ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ Π²Ρ€ΠΎΠ΄Π΅ этого:
c# var serializerOptions = new JsonSerializerOptions(); serializerOptions.Converters.Add(new DynamicJsonConverter()); return JsonSerializer.Deserialize<dynamic>("{OK:"200"}", serializerOptions);

ΠŸΠΎΠΏΡ€ΠΎΠ±ΡƒΠΉΡ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΈΠΏ JsonElement:

public JsonElement MyProperty {get; set;}

@tchivs , я внСс Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ измСнСния Π² ваш ΠΊΠΎΠ΄ - ΠΏΠ΅Ρ€Π΅Ρ€Π°Π±ΠΎΡ‚Π°Π» Π΅Π³ΠΎ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ использовал динамичСски Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅ΠΌΡ‹Π΅ "ΠΏΡ€ΠΎΠ΅ΠΊΡ†ΠΈΠΎΠ½Π½Ρ‹Π΅" Ρ‚ΠΈΠΏΡ‹ (ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΠ΅ подмноТСство свойств ΠΈΠ· Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°), Π° Π½Π΅ ExpandoObject. Π― размСстил ΠΊΠΎΠ΄ (Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° консоли) здСсь: EDennis.DynamicDeserialization .

Π― Π±ΡƒΠ΄Ρƒ Ρ‚Π΅ΡΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ этот ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ с Π±ΠΎΠ»Π΅Π΅ слоТными ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ ΠΈ Π² Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… сцСнариях (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, дСсСриализация динамичСских ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Ρ… для исправлСния ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ…, ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… сущностСй EF Core; дСсСриализация json-ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² ΠΈ массивов для тСстовых случаСв). Π”Π°ΠΉΡ‚Π΅ ΠΌΠ½Π΅ Π·Π½Π°Ρ‚ΡŒ, Ссли Π²Ρ‹ Π½Π°ΠΉΠ΄Π΅Ρ‚Π΅ это ΠΏΠΎΠ»Π΅Π·Π½Ρ‹ΠΌ ΠΈΠ»ΠΈ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°Ρ‚ΠΈΡ‡Π½ΠΎΠ΅.

Бпасибо Π·Π° ΠΎΠ±Ρ…ΠΎΠ΄Π½ΠΎΠΉ ΠΏΡƒΡ‚ΡŒ сообщСства. Π£Π΄ΠΈΠ²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ, Ρ‡Ρ‚ΠΎ Microsoft Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ эту Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Π² Ρ€Π°Π·ΡƒΠΌΠ½Ρ‹Π΅ сроки. Π Π°Π±ΠΎΡ‚Π° с ΠΎΡ‚Π²Π΅Ρ‚Π°ΠΌΠΈ GraphQL Π±Π΅Π· ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Π»ΠΈΠ±ΠΎ динамичСского ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ появлСнию большого количСства ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎΠ³ΠΎ ΠΈ ΡƒΡ€ΠΎΠ΄Π»ΠΈΠ²ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°. Или Π΄Π°ΠΆΠ΅ просто ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ Π³Π»ΡƒΠ±ΠΎΠΊΠΎ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Ρ… свойств.

Π― ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Π» Ρ†Π΅ΠΏΠΎΡ‡ΠΊΡƒ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠ΅Π², ΠΈ Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²ΠΎ ΠΈΠ· Π½ΠΈΡ… сосрСдоточСно Π½Π° дСсСриализации, я столкнулся с ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΎΠΉ, ΠΊΠΎΠ³Π΄Π° сСриализация динамичСских ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², ΠΏΠΎ-Π²ΠΈΠ΄ΠΈΠΌΠΎΠΌΡƒ, ΠΌΠΎΠ»Ρ‡Π° "Ρ‚Π΅Ρ€ΠΏΠΈΡ‚ Π½Π΅ΡƒΠ΄Π°Ρ‡Ρƒ". ΠŸΡ‹Ρ‚Π°ΡΡΡŒ воспроизвСсти свой сцСнарий, я ΠΏΡ€ΠΈΠ΄ΡƒΠΌΠ°Π» ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅ минимальноС воспроизвСдСниС:

using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Text.Json;

namespace SampleConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            dynamic d = new CustomDynamicObject();
            d.AProperty = 10;
            var s = JsonSerializer.Serialize(d);

            Console.WriteLine(s);
            Console.Read();
        }
    }

    class CustomDynamicObject : DynamicObject 
    {
        private readonly IDictionary<string, object> properties = new Dictionary<string, object>();

        public override bool TryGetMember(GetMemberBinder binder, out object result) => properties.TryGetValue(binder.Name, out result);

        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            properties[binder.Name] = value;
            return true;
        }

        public override IEnumerable<string> GetDynamicMemberNames()
        {
            foreach (var item in properties.Keys)
            {
                yield return item;
            }
        }
    }
}

ΠŸΡ€ΠΈ запускС s Ρ€Π°Π²Π½ΠΎ {} , поэтому сСриализация Π½Π΅ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ ошибкой, Π½ΠΎ Π΄Π°Π΅Ρ‚ пустой ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ json.

Π­Ρ‚ΠΎ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ вопрос? ΠΈΠ»ΠΈ я Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΏΠΎΠ΄Π½ΡΡ‚ΡŒ / ΠΏΠΎΠ΄ΠΏΠΈΡΠ°Ρ‚ΡŒΡΡ Π½Π° Π΄Ρ€ΡƒΠ³ΠΎΠΉ?

Π­Ρ‚ΠΎ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ вопрос? ΠΈΠ»ΠΈ я Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΏΠΎΠ΄Π½ΡΡ‚ΡŒ / ΠΏΠΎΠ΄ΠΏΠΈΡΠ°Ρ‚ΡŒΡΡ Π½Π° Π΄Ρ€ΡƒΠ³ΠΎΠΉ?

Π­Ρ‚ΠΎ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ вопрос. НСт нСобходимости ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Ρ‚ΡŒ ΠΎΠ΄Π½Ρƒ для Π΄Π²ΡƒΡ… ΠΏΠΎΠ»ΠΎΠ²ΠΈΠ½ΠΎΠΊ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈ Ρ‚ΠΎΠ³ΠΎ ΠΆΠ΅ элСмСнта. Π­Ρ‚Π° ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° связана с Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ΠΌ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ для ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° expando (Ρ‡Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ для ΠΎΠ±Π΅ΠΈΡ… сторон ΡΠ΅Ρ€ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ ΠΈ Π΄Π΅ΡΠ΅Ρ€ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ).

Π― столкнулся с этой ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΎΠΉ сСгодня - Ρ…ΠΎΡ‚Π΅Π» ΡΠΊΠ°Π·Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ JsonElement Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ, Ссли это Π½Π΅ зависит ΠΎΡ‚ ΡƒΠ΄Π°Π»Π΅Π½Π½ΠΎΠ³ΠΎ JsonDocument . Один ΠΈΠ· способов Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ этой ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ - Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ дСструктор для JsonDocument Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π΅Π³ΠΎ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΠΎΡ‚Π»ΠΎΠΆΠΈΡ‚ΡŒ Π½Π° Π±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ·Π΄Π½Π΅Π΅ врСмя - послС Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ всС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ JsonElement Π±ΡƒΠ΄ΡƒΡ‚ собраны.

Π•Ρ‰Π΅ ΠΌΠ½Π΅ Π½ΡƒΠΆΠ΅Π½ Π±Ρ‹Π» динамичСский ΠΎΠ±ΡŠΠ΅ΠΊΡ‚. Однако это Π΅Ρ‰Π΅ Π½Π΅ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ΠΎ. МоС Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Π±Ρ‹Π»ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ.
JsonSerializer.Deserialize<Dictionary<string, string>>(response)
А ΠΏΠΎΡ‚ΠΎΠΌ ΠΈΡ‰ΠΈ Π½ΡƒΠΆΠ½Ρ‹ΠΉ ΠΌΠ½Π΅ ΠΊΠ»ΡŽΡ‡ :)

ΠŸΡ€ΠΎΡΡ‚ΠΎ для ΠΌΠΎΠ΅Π³ΠΎ рассудка - относится Π»ΠΈ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° ΠΊ 5.0, Π² частности, ΠΊ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ΅ ExpandoObject ΠΈΠ»ΠΈ возмоТности дСсСриализации Π² динамичСский ΠΎΠ±ΡŠΠ΅ΠΊΡ‚? НС всС Ρ€Π°Π·Π³ΠΎΠ²ΠΎΡ€Ρ‹ здСсь ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‚ названию ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹, ΠΈ ΠΌΠ½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎ Π½ΡƒΠΆΠ½ΠΎ послСднСС. Π’ ΠΌΠΎΠ΅ΠΌ случаС я Π΄Π΅ΡΠ΅Ρ€ΠΈΠ°Π»ΠΈΠ·ΡƒΡŽ Π²Π»ΠΎΠΆΠ΅Π½Π½ΡƒΡŽ Π΄ΠΈΠ½Π°ΠΌΠΈΠΊΡƒ, Π² частности List<Dictionary<string, dynamic>> . На Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡ΠΈΠ»ΡΡ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ Π½Π° Newtonsoft :(

просто Ρ…ΠΎΡ‚Π΅Π» ΠΏΠΎΠ΄Π΅Π»ΠΈΡ‚ΡŒΡΡ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌΠΈ модификациями синтаксиса C # 8 для ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°

/// <summary>
/// Temp Dynamic Converter with c# 8
/// by:[email protected]
/// </summary>
public class DynamicJsonConverter : JsonConverter<dynamic>
{
    public override dynamic Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        => reader.TokenType switch
        {
            JsonTokenType.True => true,
            JsonTokenType.False => false,
            JsonTokenType.Number => reader.TryGetInt64(out long l) ? 1 : reader.GetDouble(),
            JsonTokenType.String => reader.TryGetDateTime(out DateTime datetime) ? datetime.ToString() : reader.GetString(),
            JsonTokenType.StartObject =>  ReadObject(JsonDocument.ParseValue(ref reader).RootElement),
            // Use JsonElement as fallback.
                _ =>JsonDocument.ParseValue(ref reader).RootElement.Clone()
        };

    private object ReadObject(JsonElement jsonElement)
    {
        IDictionary<string, object> expandoObject = new ExpandoObject();
        foreach (var obj in jsonElement.EnumerateObject())
        {
            var k = obj.Name;
            var value = ReadValue(obj.Value);
            expandoObject[k] = value;
        }
        return expandoObject;
    }
    private object? ReadValue(JsonElement jsonElement)
        =>
         jsonElement.ValueKind switch
        {
            JsonValueKind.Object => ReadObject(jsonElement),
            JsonValueKind.Array => ReadList(jsonElement),
            JsonValueKind.String => jsonElement.GetString(),
            JsonValueKind.Number =>  jsonElement.TryGetInt64(out long l) ? 1 :0,
            JsonValueKind.True => true,
            JsonValueKind.False =>false,
            JsonValueKind.Undefined => null,
            JsonValueKind.Null => null,
                _ => throw new ArgumentOutOfRangeException()
        };

    private object? ReadList(JsonElement jsonElement)
    {
        var list = new List<object?>();
        jsonElement.EnumerateArray().ToList().ForEach(j => list.Add(ReadValue(j)));
        return list.Count == 0 ? null : list;
    }

    public override void Write(Utf8JsonWriter writer,
        object value,
        JsonSerializerOptions options)
        {
        // writer.WriteStringValue(value.ToString());
        }
}

@ rs38 спасибо Π·Π° ΠΊΠΎΠ΄, это ΠΈΠΌΠ΅Π½Π½ΠΎ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ ΠΌΠ½Π΅ Π½ΡƒΠΆΠ½ΠΎ. Π₯ΠΎΡ‚Π΅Π» ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ Π½Π° ΠΎΡ‡Π΅Π½ΡŒ Ρ‚ΠΎΠ½ΠΊΠΎΠ΅, Π½ΠΎ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅. Π”Π²Π΅ строки, Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠ΅ Ρ‚ΠΈΠΏ «Число», Π½Π΅Π²Π΅Ρ€Π½Ρ‹ Π² вашСй сТатой вСрсии:

JsonTokenType.Number => reader.TryGetInt64(out long l) ? 1 : reader.GetDouble(),

Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ

JsonTokenType.Number => reader.TryGetInt64(out long l) ? l : reader.GetDouble(),

JsonValueKind.Number => jsonElement.TryGetInt64(out long l) ? 1 :0,

Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ

JsonValueKind.Number => jsonElement.TryGetInt64(out long l) ? l :0,

@layomia Π­Ρ‚ΠΎ Π½Π΅ΡΠ΅Ρ€ΡŒΠ΅Π·Π½ΠΎ. ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Π»Π° Π±Ρ‹Ρ‚ΡŒ сдСлана Π΄Π°Π²Π½ΠΎ (Π½Π° самом Π΄Π΅Π»Π΅, Π½Π° ΠΌΠΎΠΉ взгляд, System.Text.Json Π½Π΅ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Π» Π·Π°ΠΏΡƒΡΠΊΠ°Ρ‚ΡŒΡΡ Π±Π΅Π· Π½Π΅Π΅)! А Ρƒ нас Π΄Π°ΠΆΠ΅ Π΄Π΅Π΄Π»Π°ΠΉΠ½Π° Π½Π΅Ρ‚!

Мой сцСнарий касаСтся CosmosDB. Π― Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°ΡŽ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π½ΠΎΠ²ΠΎΠ³ΠΎ .NET SDK, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ этот JsonSerializer, ΠΈ, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ это Π±Π°Π·Π° Π΄Π°Π½Π½Ρ‹Ρ… Π±Π΅Π· схСмы, я Π½Π΅ Ρ…ΠΎΡ‡Ρƒ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ класс для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΏΡ€ΠΎΠ΅ΠΊΡ†ΠΈΠΈ Π΄Π°Π½Π½Ρ‹Ρ… Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠ½Π΅ Π½ΡƒΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ (сущСствуСт мноТСство Ρ€Π°Π·Π½Ρ‹Ρ… запросов) .
МнС Π½ΡƒΠΆΠ½Ρ‹ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ запросов Π² Π²ΠΈΠ΄Π΅ списков динамичСских ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ².

@ SocVi100 НС @layomia развСяла всС Π½Π°Π΄Π΅ΠΆΠ΄Ρ‹ Π½Π° ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΡŽ Π² блиТайшСм Π±ΡƒΠ΄ΡƒΡ‰Π΅ΠΌ. ΠŸΠΎΡ…ΠΎΠΆΠ΅, ΠΈΠΌ Π½Π°ΠΏΠ»Π΅Π²Π°Ρ‚ΡŒ Π½Π° Π½ΡƒΠΆΠ΄Ρ‹ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°. Π‘Π½Π°Ρ‡Π°Π»Π° ΠΎΠ½ΠΈ ΠΊΡ€ΠΈΡ‡Π°Π»ΠΈ: Β«Π—Π°Π±ΡƒΠ΄ΡŒΡ‚Π΅ ΠΎ json.net, ΠΌΡ‹ вас ΠΏΡ€ΠΈΠΊΡ€Ρ‹Π»ΠΈ!Β» К ΡΡ‡Π°ΡΡ‚ΡŒΡŽ, Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ Π½Π΅ Π·Π°Π±Ρ‹Π»ΠΈ ΠΏΡ€ΠΎ json.net ΠΈ Ρ‚ΠΎΠΌΡƒ ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎΠ΅.

ΠΏΠΎΡ‡Π΅ΠΌΡƒ Ρ‚Ρ‹ Π½Π΅ ΡƒΡ‡Π°ΡΡ‚Π²ΡƒΠ΅ΡˆΡŒ? Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ ΠΏΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π² ΠΏΠΈΠ°Ρ€!

https://github.com/dotnet/runtime/blob/master/docs/coding-guidelines/adding-api-guidelines.md
https://github.com/dotnet/runtime/blob/master/docs/area-owners.md (Ρ€ΡƒΠΊΠΎΠ²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒ:
@ericstj |, Π²Π»Π°Π΄Π΅Π»ΡŒΡ†Ρ‹: @layomia @steveharter @jozkee)

ΠΏΠΎΡ‡Π΅ΠΌΡƒ Ρ‚Ρ‹ Π½Π΅ ΡƒΡ‡Π°ΡΡ‚Π²ΡƒΠ΅ΡˆΡŒ? Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ ΠΏΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π² ΠΏΠΈΠ°Ρ€!

Π― Π±Ρ‹ Ρ…ΠΎΡ‚Π΅Π».

Мой сцСнарий касаСтся CosmosDB. Π― Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°ΡŽ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π½ΠΎΠ²ΠΎΠ³ΠΎ .NET SDK, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ этот JsonSerializer, ΠΈ, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ это Π±Π°Π·Π° Π΄Π°Π½Π½Ρ‹Ρ… Π±Π΅Π· схСмы, я Π½Π΅ Ρ…ΠΎΡ‡Ρƒ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ класс для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΏΡ€ΠΎΠ΅ΠΊΡ†ΠΈΠΈ Π΄Π°Π½Π½Ρ‹Ρ… Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠ½Π΅ Π½ΡƒΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ (сущСствуСт мноТСство Ρ€Π°Π·Π½Ρ‹Ρ… запросов) .
МнС Π½ΡƒΠΆΠ½Ρ‹ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ запросов Π² Π²ΠΈΠ΄Π΅ списков динамичСских ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ².

МоТно Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ Π΄Ρ€ΡƒΠ³ΠΎΠΉ сСриализатор с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ CosmosClientBuilder.WithCustomSerializer .

Π’ΠΎΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€: CosmosJsonNetSerializer

ΠœΡ‹ Π½Π΅ смогли ΡƒΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ эту Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Π² 5.0. Нам ΠΏΡ€ΠΈΡˆΠ»ΠΎΡΡŒ Ρ€Π°ΡΡΡ‚Π°Π²ΠΈΡ‚ΡŒ ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚Ρ‹ вмСстС с ΠΎΡΡ‚Π°Π»ΡŒΠ½ΠΎΠΉ Ρ€Π°Π±ΠΎΡ‚ΠΎΠΉ Π½Π°Π΄ функциями 5.0, ΠΈ эта Π½Π΅ подошла. FWIW это Π±Ρ‹Π»ΠΎ ΠΎΡ‡Π΅Π½ΡŒ Π±Π»ΠΈΠ·ΠΊΠΎ ΠΊ Π»ΠΈΠ½ΠΈΠΈ Ρ€Π°Π·Ρ€Π΅Π·Π°, ΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, ΠΏΠΎΠ·Π΄Π½ΠΈΠΉ Ρ…ΠΎΠ΄.

@layomia развСяла всС Π½Π°Π΄Π΅ΠΆΠ΄Ρ‹ Π½Π° ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΡŽ Π² блиТайшСм Π±ΡƒΠ΄ΡƒΡ‰Π΅ΠΌ. ΠŸΠΎΡ…ΠΎΠΆΠ΅, ΠΈΠΌ Π½Π°ΠΏΠ»Π΅Π²Π°Ρ‚ΡŒ Π½Π° Π½ΡƒΠΆΠ΄Ρ‹ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°. Π‘Π½Π°Ρ‡Π°Π»Π° ΠΎΠ½ΠΈ ΠΊΡ€ΠΈΡ‡Π°Π»ΠΈ: Β«Π—Π°Π±ΡƒΠ΄ΡŒΡ‚Π΅ ΠΎ json.net, ΠΌΡ‹ вас ΠΏΡ€ΠΈΠΊΡ€Ρ‹Π»ΠΈ!Β» К ΡΡ‡Π°ΡΡ‚ΡŒΡŽ, Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ Π½Π΅ Π·Π°Π±Ρ‹Π»ΠΈ ΠΏΡ€ΠΎ json.net ΠΈ Ρ‚ΠΎΠΌΡƒ ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎΠ΅.

@RobbyDeLaet, ΠΌΠΎΠΆΠ΅ΠΌ Π»ΠΈ ΠΌΡ‹ ΠΏΠΎΠΏΡ‹Ρ‚Π°Ρ‚ΡŒΡΡ ΡΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ ΠΊΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ‚ΠΈΠ²Π½ΠΎΡΡ‚ΡŒ этого обсуТдСния? ΠœΡ‹ стараСмся ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ всС Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠ΅, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ΄ΠΎΠ²Π»Π΅Ρ‚Π²ΠΎΡ€ΠΈΡ‚ΡŒ самыС популярныС запросы ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ², сохраняя ΠΏΡ€ΠΈ этом ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΡ‹ Π΄ΠΈΠ·Π°ΠΉΠ½Π°. Π§Ρ‚ΠΎ касаСтся ΠΏΠ°Ρ€ΠΈΡ‚Π΅Ρ‚Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ с Newtonsoft.Json, Π²ΠΎΡ‚ Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡΠΊΠ°Π·Π°Ρ‚ΡŒ .

System.Text.Json Π² ΠΏΠ΅Ρ€Π²ΡƒΡŽ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ ΠΎΡ€ΠΈΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ Π½Π° ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ, Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ‚ΡŒ ΠΈ соотвСтствиС стандартам. Для Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… сцСнариСв System.Text.Json Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ встроСнных Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, Π½ΠΎ Π΅ΡΡ‚ΡŒ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΠ΅ΠΌΡ‹Π΅ ΠΎΠ±Ρ…ΠΎΠ΄Π½Ρ‹Π΅ ΠΏΡƒΡ‚ΠΈ. Если вашС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ зависит ΠΎΡ‚ ΠΎΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, рассмотритС Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ рСгистрации ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ·Π½Π°Ρ‚ΡŒ, ΠΌΠΎΠΆΠ½ΠΎ Π»ΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ для вашСго сцСнария.

ΠœΡ‹ Π½Π΅ стрСмимся Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Newtonsoft.JSON. Если это сработало, ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°ΠΉΡ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ. ΠœΡ‹ сдСлаСм всС Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠ΅, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ System.Text.Json максимально ΠΏΠΎΠ»Π΅Π·Π½Ρ‹ΠΌ, сохранив ΠΏΡ€ΠΈ этом достигнутыС Π½Π°ΠΌΠΈ успСхи Π² ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ, бСзопасности, соотвСтствии стандартам ΠΈ многоуровнСвости. Π‘ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ ΠΌΡ‹ надССмся, Ρ‡Ρ‚ΠΎ это сработаСт для ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ большСго числа людСй. Π― ΡΠ»Ρ‹ΡˆΡƒ здСсь интСрСс ΠΈ ΠΏΠΎΡΡ‚Π°Ρ€Π°ΡŽΡΡŒ ΡΠΎΡΡ€Π΅Π΄ΠΎΡ‚ΠΎΡ‡ΠΈΡ‚ΡŒΡΡ Π½Π° этом Π² дальнСйшСм.

Бпасибо Π·Π° ваши прСдлоТСния. Π― Π½Π°ΠΊΠΎΠ½Π΅Ρ† дошСл Π΄ΠΎ сСрСдины, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ сСриализатор Newtonsoft Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для дСсСриализации, Π½ΠΎ ΠΌΠ½Π΅ всС Π΅Ρ‰Π΅ Π½ΡƒΠΆΠ½ΠΎ ΠΏΡ€ΠΎΡ‚Π΅ΡΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ. Π― надСюсь, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° ExpandoObject Π² сСриализаторС ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ CosmosDB Π½Π΅ продлится слишком Π΄ΠΎΠ»Π³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ я ΠΌΠΎΠ³ ΠΈΠ·Π±Π°Π²ΠΈΡ‚ΡŒΡΡ ΠΎΡ‚ старого.
@RobbyDeLaet , спасибо Π·Π° ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ! Π£ мСня Π½Π΅Ρ‚ особых Π½Π°Π΄Π΅ΠΆΠ΄ Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Microsoft Π²Π½Π΅Π΄Ρ€ΠΈΡ‚ ΠΊΠ°ΠΊΠΈΠ΅-Π»ΠΈΠ±ΠΎ элСмСнты, я слишком ΠΌΠ½ΠΎΠ³ΠΎ Ρ€Π°Π· разочаровывался Π² Π½ΠΈΡ…. Как Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ-фрилансСр, я Π³ΠΎΠ΄Π°ΠΌΠΈ Π±ΡƒΠΊΠ²Π°Π»ΡŒΠ½ΠΎ ΠΆΠ΄Π°Π», ΠΏΠΎΠΊΠ° Π²Π°ΠΆΠ½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π±ΡƒΠ΄ΡƒΡ‚ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Ρ‹ Π² инфраструктурС CosmosDB, EntityFramework ΠΈ Identity, ΠΈ ΠΎΠ½ΠΈ ΠΏΠΎ-своСму ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΡƒΡŽΡ‚ нас. НСваТно, сколько Ρƒ Π½ΠΈΡ… голосов Π½Π° UserVoice ΠΈΠ»ΠΈ Ρ‡Π΅ΠΌ-Ρ‚ΠΎ Π΅Ρ‰Π΅. Π― ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°ΡŽ, Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π½Π΅ Π½ΡƒΠΆΠ½Ρ‹ для Π΅Π³ΠΎ собствСнных Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΎΠΊ, поэтому ΠΎΠ½ΠΈ выходят Π·Π° Ρ€Π°ΠΌΠΊΠΈ ...
ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ° всСгда ΠΎΠ΄Π½Π° ΠΈ Ρ‚Π° ΠΆΠ΅: слишком ΠΌΠ½ΠΎΠ³ΠΎ ΠΌΠ°Ρ€ΠΊΠ΅Ρ‚ΠΈΠ½Π³Π° = слишком ΠΌΠ½ΠΎΠ³ΠΎ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠΉ.

Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠΌΠΎΡ‡ΡŒ Ρ‚Π΅ΠΌ, ΠΊΠΎΠΌΡƒ Π½ΡƒΠΆΠ½Π° эта функция, см. ΠŸΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹Π΅ Π²Ρ‹ΡˆΠ΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ ΠΊΠΎΠ΄Π° для Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ:

  • ΠžΡ‚ @tchivs (ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ExpandoObject для ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² ΠΈ List<object> для ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΠΉ)
  • ΠžΡ‚ @denmitchell (ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ IL Emit для ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² вмСсто ExpandoObject )

Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠΌΠΎΡ‡ΡŒ с трСбованиями ΠΊ этой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, я ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡŽ Π½ΠΎΠ²Ρ‹ΠΉ ΠΎΠ±Ρ€Π°Π·Π΅Ρ† настраиваСмого ΠΊΠΎΠ½Π²Π΅Ρ€Ρ‚Π΅Ρ€Π° ΠΈ свяТу Π΅Π³ΠΎ здСсь, ΠΊΠΎΠ³Π΄Π° ΠΎΠ½ Π±ΡƒΠ΄Π΅Ρ‚ Π³ΠΎΡ‚ΠΎΠ². ПослС этого я добавлю этот ΠΎΠ±Ρ€Π°Π·Π΅Ρ† Π² Ρ€Π°Π·Π΄Π΅Π» ΠΎΠ±Ρ…ΠΎΠ΄Π½Ρ‹Ρ… Ρ€Π΅ΡˆΠ΅Π½ΠΈΠΉ Newtonsoft . cc @tdykstra

Одна Π΄Π΅Ρ‚Π°Π»ΡŒ, которая Π΅Ρ‰Π΅ Π½Π΅ ΠΎΠ±ΡΡƒΠΆΠ΄Π°Π»Π°ΡΡŒ, Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ для ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ dynamic трСбуСтся ссылка Π½Π° ΠΎΡ‡Π΅Π½ΡŒ Π±ΠΎΠ»ΡŒΡˆΡƒΡŽ сборку System.Linq.Expressions.dll ; это ослоТнСниС ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΠ·Π½Π°Ρ‡Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π² Π±ΡƒΠ΄ΡƒΡ‰Π΅ΠΌ ΠΌΡ‹ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ динамичСский ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π² Π½ΠΎΠ²ΡƒΡŽ сборку (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, System.Text.Json.Converters.dll ), Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΏΠ»Π°Ρ‚Ρƒ Π·Π° ΠΈΠ³Ρ€Ρƒ для Ρ‚Π΅Ρ…, ΠΊΡ‚ΠΎ заботится ΠΎ Ρ€Π°Π·ΠΌΠ΅Ρ€Π΅ развСртывания (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π°Π²Ρ‚ΠΎΠ½ΠΎΠΌΠ½ΠΎΠ΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈΠ»ΠΈ Blazor клиСнтскоС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅).

ΠŸΡ€ΠΎΡΡ‚ΠΎ для ΠΌΠΎΠ΅Π³ΠΎ рассудка - относится Π»ΠΈ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° ΠΊ 5.0, Π² частности, ΠΊ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ΅ ExpandoObject ΠΈΠ»ΠΈ возмоТности дСсСриализации Π² динамичСский ΠΎΠ±ΡŠΠ΅ΠΊΡ‚? НС всС Ρ€Π°Π·Π³ΠΎΠ²ΠΎΡ€Ρ‹ здСсь ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‚ названию ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹, ΠΈ ΠΌΠ½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎ Π½ΡƒΠΆΠ½ΠΎ послСднСС. Π’ ΠΌΠΎΠ΅ΠΌ случаС я Π΄Π΅ΡΠ΅Ρ€ΠΈΠ°Π»ΠΈΠ·ΡƒΡŽ Π²Π»ΠΎΠΆΠ΅Π½Π½ΡƒΡŽ Π΄ΠΈΠ½Π°ΠΌΠΈΠΊΡƒ, Π² частности List<Dictionary<string, dynamic>> . На Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡ΠΈΠ»ΡΡ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ Π½Π° Newtonsoft :(

БСйчас я Ρ‚Π΅ΡΡ‚ΠΈΡ€ΡƒΡŽ ΡΡ‚Π°Ρ€ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π» для дСсСриализации Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Ρ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², ΠΈ Π²ΠΈΠΆΡƒ Ρ‚Ρƒ ΠΆΠ΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ, Ρ‡Ρ‚ΠΎ ΠΈ Π² этом Ρ€Π°Π·Π΄Π΅Π»Π΅, с Β«valueKindΒ».

Π‘Ρ‹Π» Π»ΠΈ способ ΠΈΡΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ это с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π½ΠΎΠ²Ρ‹Ρ… ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ² neetonsoft.json? ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹ΠΉ Π²Ρ‹ΡˆΠ΅ ΠΊΠΎΠ΄ Ρ€Π°Π±ΠΎΡ‚Π°Π» для ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠ³ΠΎ уровня, Π½ΠΎ Π½Π΅ для Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Ρ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ².

@ericstj Π˜Π·Π²ΠΈΠ½ΠΈΡ‚Π΅, моя рСакция Π±Ρ‹Π»Π°, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, слишком Π½Π΅Π³Π°Ρ‚ΠΈΠ²Π½ΠΎΠΉ ΠΈ Ρ€Π΅Π·ΠΊΠΎΠΉ, Π½ΠΎ, ΠΊΠ°ΠΊ ΠΈ @ SocVi100, я Π²Π½Π΅ΡˆΡ‚Π°Ρ‚Π½Ρ‹ΠΉ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ, ΠΈ ΠΈΠ½ΠΎΠ³Π΄Π° Ρ€Π°Π·ΠΎΡ‡Π°Ρ€ΠΎΠ²Π°Π½ΠΈΠ΅

ΠŸΡ€ΠΎΡΡ‚ΠΎ для ΠΌΠΎΠ΅Π³ΠΎ рассудка - это ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°, относящаяся ΠΊ 5.0, Π² частности, ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° ExpandoObject ΠΈΠ»ΠΈ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ дСсСриализации Π² динамичСский ΠΎΠ±ΡŠΠ΅ΠΊΡ‚

Π― ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°ΡŽ, Ρ‡Ρ‚ΠΎ ТСлаСмая сСмантика Π΄ΠΎΠ»ΠΆΠ½Π° ΠΈΠΌΠ΅Ρ‚ΡŒ динамичСский Ρ‚ΠΈΠΏ, поэтому послС дСсСриализации Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ доступ ΠΊΠΎ всСм свойствам (Π²ΠΊΠ»ΡŽΡ‡Π°Ρ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅) с ΠΏΠΎΠ·Π΄Π½ΠΈΠΌ связываниСм:

dynamic obj = JsonSerializer.Deserialize<dynamic>(json);
string s = obj.MyChildProperty.MyStringList[2];

ΠΈ я ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°ΡŽ, Ρ‡Ρ‚ΠΎ ТСлаСмая сСмантика Ρ‚Π°ΠΊΠΆΠ΅ явно ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ ExpandoObject :

ExpandoObject expando = JsonSerializer.Deserialize<ExpandoObject>(json);
dynamic obj = expando;
string s = obj.MyChildProperty.MyStringList[2];

Π˜Ρ‚Π°ΠΊ, ΠΌΠΎΠ΅ ΠΏΠΎΠ½ΠΈΠΌΠ°Π½ΠΈΠ΅ объСма:

  • Deserialize<dynamic>(json) Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π»ΠΈΠ±ΠΎ ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ², Π»ΠΈΠ±ΠΎ ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΡŽ, Π»ΠΈΠ±ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚. Π—Π΄Π΅ΡΡŒ, скорСС всСго, Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ExpandoObject Π½ΠΎ Π² зависимости ΠΎΡ‚ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ IDynamicMetaObjectProvider ΠΈΠ»ΠΈ JITed-Ρ‚ΠΈΠΏΠΎΠΌ. Π­Ρ‚ΠΎ отличаСтся ΠΎΡ‚ сСгодняшнСго, ΠΊΠΎΠ³Π΄Π° всСгда возвращаСтся JsonElement .
  • Deserialize<ExpandoObject>(json) (ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ IDynamicMetaObjectProvider ) Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ ExpandoObject ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ, Π² свою ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ, ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ с dynamic . Π­Ρ‚ΠΎ отличаСтся ΠΎΡ‚ сСгодняшнСго дня, ΠΊΠΎΠ³Π΄Π° ΡΠΎΠ·Π΄Π°ΡŽΡ‚ΡΡ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½Π½Ρ‹Π΅ свойства Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для ΠΊΠΎΡ€Π½Π΅Π²Ρ‹Ρ… свойств ΠΈ экзСмпляров JsonElement для всСх Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Ρ… свойств.
  • Serialize<ExpandoObect>() Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ
  • Serialize<IDynamicMetaObjectProvider ()> ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΠ»ΠΈ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ΠΎ Π² зависимости ΠΎΡ‚ Ρ‚ΠΎΠ³ΠΎ, ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ Π»ΠΈ сцСнарии, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ExpandoObject Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ.

Π‘Π΅ΠΌΠ°Π½Ρ‚ΠΈΠΊΠ° Π² 3.0 - 5.0:

  • БСриализация ExpandoObject Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ExpandoObject Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ IDictionary<string, object> Π° STJ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ сСриализуСт ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ object Π±ΡƒΠ΄ΡŒ Ρ‚ΠΎ ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ², коллСкция ΠΈΠ»ΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚.
  • ДСсСриализация Π² Π²ΠΈΠ΄ ExpandoObject Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚, Π½ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊΠΎΡ€Π½Π΅Π²Ρ‹Π΅ свойства ΡΠ²Π»ΡΡŽΡ‚ΡΡ Β«ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΌΠΈΒ» Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅ΠΌΡ‹ΠΌΠΈ свойствами; Π»ΡŽΠ±Ρ‹Π΅ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ свойства Π±ΡƒΠ΄ΡƒΡ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ Π²ΠΈΠ΄ JsonElement поэтому Π² ΠΌΠΎΠ΄Π΅Π»ΠΈ программирования сущСствуСт Π½Π΅ΡΠΎΠ³Π»Π°ΡΠΎΠ²Π°Π½Π½ΠΎΡΡ‚ΡŒ, поэтому слСдуСт ΠΈΠ·Π±Π΅Π³Π°Ρ‚ΡŒ дСсСриализации ExpandoObject Ссли для этого Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ.

Π’Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹ 3.0-5.0:

  • ΠΠ°ΠΏΠΈΡˆΠΈΡ‚Π΅ собствСнный ΠΊΠΎΠ½Π²Π΅Ρ€Ρ‚Π΅Ρ€ для ExpandoObject ΠΈ \ ΠΈΠ»ΠΈ object ΠΊΠ°ΠΊ ΡƒΠΊΠ°Π·Π°Π½ΠΎ Π² сообщСниях Π²Ρ‹ΡˆΠ΅; Π― скоро ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡŽ ссылку Π½Π° Π½ΠΎΠ²Ρ‹ΠΉ ΠΎΠ±Ρ€Π°Π·Π΅Ρ†, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ идСально соотвСтствуСт Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ 6.0.
  • Если Π²Ρ‹ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ сСриализуСтС, Π° Π½Π΅ дСсСриализуСтС, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ExpandoObject (ΠΈΠ»ΠΈ dynamic Ссли Ρ‚ΠΈΠΏ основан Π½Π° ExpandoObject ). ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ дСсСриализация ExpandoObject ΠΈΠΌΠ΅Π΅Ρ‚ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ нСсогласованности Π² STJ, ExpandoObject Π½Π΅ рСкомСндуСтся ΠΏΡ€ΠΈ дСсСриализации.
  • Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ JsonElement вмСсто динамичСских ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ². JsonElement Π½Π΅ пытаСтся Β«ΡƒΠ³Π°Π΄Π°Ρ‚ΡŒΒ», ΠΊΠ°ΠΊΠΎΠΌΡƒ Ρ‚ΠΈΠΏΡƒ сопоставляСтся JSON, поэтому Π²Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ явно ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ, вызывая GetString (), GetInt32 () ΠΈ Ρ‚. Π”.

ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, Π² зависимости ΠΎΡ‚ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ рСализация настраиваСмого ΠΊΠΎΠ½Π²Π΅Ρ€Ρ‚Π΅Ρ€Π°, вСроятно, ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Β«Π΄ΠΎΠ³Π°Π΄ΠΊΠΈΒ» ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊΠΈΠ΅ Ρ‚ΠΈΠΏΡ‹ CLR ΡΠΎΠΏΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‚ΡΡ JSON Π²ΠΎ врСмя дСсСриализации. НапримСр, строка JSON ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Ρ‚ΡŒΡΡ Π»ΠΈΠ±ΠΎ Π½Π° DateTime ΠΈΠ»ΠΈ Π½Π° string , Π½ΠΎΠΌΠ΅Ρ€ JSON ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Ρ‚ΡŒΡΡ Π½Π° double ΠΈΠ»ΠΈ long , Π° НСобходимо ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ Ρ‚ΠΈΠΏ массива JSON. Π­Ρ‚ΠΎ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ ΠΈ ΡΡ€Π°Π²Π½ΠΈΡ‚ΡŒ с сСмантикой Newtonsoft. Π­Ρ‚ΠΎ Ρ‚Π°ΠΊΠΆΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΎΠΌΡƒ, ΠΊΠ°ΠΊΠΎΠΉ Ρ‚ΠΈΠΏ возвращаСтся, ΠΊΠΎΠ³Π΄Π° свойство ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‚ΠΈΠΏ object (сСгодня это JsonElement ).

Π’ΠΎΡ‚ нСсколько ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠ² сСмантики 3.0 - 5.0 STJ:

using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Diagnostics;
using System.Linq;
using System.Text.Json;

namespace ConsoleApp
{
    class Program
    {
        const string ExpectedJson = "{\"A\":\"A\",\"B\":[1,2],\"C\":42,\"D\":\"2020-01-01T00:00:00\",\"E\":{\"A_Child\":\"A_Child\"}}";

        static void Main(string[] args)
        {
            DateTime dateTime = new DateTime(2020, 1, 1);

            dynamic myDynamicChild = new ExpandoObject();
            myDynamicChild.A_Child = "A_Child";

            dynamic myDynamic = new ExpandoObject();
            myDynamic.A = "A";
            myDynamic.B = new List<int>() { 1, 2 };
            myDynamic.C = 42;
            myDynamic.D = dateTime;
            myDynamic.E = myDynamicChild;

            // Verify we can call late-bound property.
            int c = myDynamic.C;
            Debug.Assert(c == 42);

            // STJ can serialize with ExpandoObject since it implements IDictionary<string, object>.
            string json = JsonSerializer.Serialize<ExpandoObject>(myDynamic);
            Debug.Assert(json == ExpectedJson);

            // Using 'dynamic' against backing ExpandoObject works.
            json = JsonSerializer.Serialize<dynamic>(myDynamic);
            Debug.Assert(json == ExpectedJson);

            // Deserialize with <dynamic>, <object> and <JsonElement>.
            // For 5.0, using one of these is recommended over ExpandoObject because the programming model will be
            // consistent for the root type and all nested types.
            // Using <JsonElement> makes it clear and non-abiguous.
            // Using <object> by default uses 'JsonElement', but can be overridden by a custom converter.
            // Using <dynamic> uses 'object' which uses 'JsonElement'.
            {
                dynamic d = JsonSerializer.Deserialize<dynamic>(json);
                VerifyJsonElement(d);

                try
                {
                    // We will get an exception here if we try to access a dynamic property since 'object' is deserialized
                    // as a JsonElement and not an ExpandoObject.
                    c = d.C;
                    Debug.Fail("Should have thrown Exception!");
                }
                catch (Exception ex)
                {
                    Debug.Assert(ex.Message == "'System.Text.Json.JsonElement' does not contain a definition for 'C'");
                }

                // Serializing with <object> creates a JsonElement by default (can be changed by a custom converter).
                object o = JsonSerializer.Deserialize<object>(json);
                VerifyJsonElement((JsonElement)o);

                // Serialize with explicit <JsonElement>.
                JsonElement e = JsonSerializer.Deserialize<JsonElement>(json);
                VerifyJsonElement(e);
            }

            // Deserialize with ExpandoObject. This creates an ExpandoObject with the root Type having Expando-properties
            // but the value of those properties will be JsonElement. All other nested properties\objects\collections will
            // also be JsonElement. Due to the inconsistency of having only root-level Expando-properties (such as A_Child),
            // deserializing as ExpandoObject is not recommended (unless a ExpandoObject custom converter is used).
            {
                // When STJ deserializes, it creates ExpandoObjects via IDictionary<string, object> where 'object' is JsonElement.
                ExpandoObject expando = JsonSerializer.Deserialize<ExpandoObject>(json);
                Debug.Assert(((IDictionary<string, object>)expando).Keys.Count == 5);
                myDynamic = expando;

                JsonElement jsonElement = myDynamic.A;
                Debug.Assert(jsonElement.GetString() == "A");

                jsonElement = myDynamic.B;
                Debug.Assert(jsonElement.EnumerateArray().Count() == 2);

                jsonElement = myDynamic.C;
                Debug.Assert(jsonElement.GetInt32() == 42);

                jsonElement = myDynamic.D;
                Debug.Assert(jsonElement.GetDateTime() == dateTime);

                jsonElement = myDynamic.E;
                // Here we have an inconsistency. Nested object property must use JsonElement (not a dynamic property).
                Debug.Assert(jsonElement.GetProperty("A_Child").GetString() == "A_Child");

                // Re-serialize works as expected.
                json = JsonSerializer.Serialize<ExpandoObject>(myDynamic);
                Debug.Assert(json == ExpectedJson);

                // Re-serialize works as expected; dynamic works here since backed by ExpandoObject in this example.
                json = JsonSerializer.Serialize<dynamic>(myDynamic);
                Debug.Assert(json == ExpectedJson);
            }

            void VerifyJsonElement(JsonElement elem)
            {
                // Verify JsonElement
                Debug.Assert(elem.GetProperty("A").GetString() == "A");
                Debug.Assert(elem.GetProperty("B").EnumerateArray().Count() == 2);
                Debug.Assert(elem.GetProperty("C").GetInt32() == 42);
                Debug.Assert(elem.GetProperty("D").GetDateTime() == dateTime);
                Debug.Assert(elem.GetProperty("E").GetProperty("A_Child").GetString() == "A_Child");

                // Re-serialize
                json = JsonSerializer.Serialize<dynamic>(elem);
                Debug.Assert(json == ExpectedJson);

                json = JsonSerializer.Serialize<JsonElement>(elem);
                Debug.Assert(json == ExpectedJson);
            }
        }
    }
}

@ rs38 ΠœΠΎΠΆΠ΅Ρ‚Π΅ Π»ΠΈ Π²Ρ‹ ΠΈΡΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ ΠΊΠΎΠ΄Π° Π½Π° основС Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ ΡƒΠΊΠ°Π·Π°Π» @ ryan-hollister-q2?

Как ΠΈ Π±Ρ‹Π»ΠΎ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΎ, PR с ΠΎΠ±Ρ€Π°Π·Ρ†ΠΎΠΌ динамичСской Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ находится ΠΏΠΎ адрСсу https://github.com/dotnet/runtime/pull/42097.

@ rs38 ΠœΠΎΠΆΠ΅Ρ‚Π΅ Π»ΠΈ Π²Ρ‹ ΠΈΡΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ ΠΊΠΎΠ΄Π° Π½Π° основС Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ ΡƒΠΊΠ°Π·Π°Π» @ ryan-hollister-q2?

это Π±Ρ‹Π» Π½Π΅ ΠΌΠΎΠΉ ΠΊΠΎΠ΄, просто подСлился Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌΠΈ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π°ΠΌΠΈ ΠΈΠ· @tchivs Ρ€Π°Π½Π΅Π΅ Π² этом ΠΏΠΎΡ‚ΠΎΠΊΠ΅.

Π‘Ρ‹Π»Π° Π»ΠΈ эта страница ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ?
0 / 5 - 0 Ρ€Π΅ΠΉΡ‚ΠΈΠ½Π³ΠΈ