.NET Core 3.0 미리 보기 7
Asp.NET Web APIλ μ¬μ μ λ°νν λ NotSupportedExceptionκ³Ό ν¨κ» μ€ν¨ν©λλ€. μλμ μμΈλ₯Ό ν¬ν¨νμ΅λλ€.
λν ControllerBase.BadRequest
λ©μλλ ModelStateDictionary
λ₯Ό λ°μ§λ§ λ°νλλ©΄ μ§λ ¬ λ³νκΈ°λ NotSupportedExceptionκ³Ό ν¨κ» νλ°νμ§λ§ μ½κ° λ€λ₯Έ λ©μμ§κ° νμλ©λλ€.
μ΄ μ§μμ μΈμ μΆκ°λλμ? μ΄κ²μ Json.net λ° κΈ°ν μ§λ ¬ λ³νκΈ°μμ μ μ λμ μ§μλμκΈ° λλ¬Έμ μ΄κ²μ΄ λ μ΄λμ μκΈ°λ₯Ό λ°λλλ€.
Json.netμ λ€μ μ¬μ©νλλ‘ μ νν μ μλ€λ μ¬μ€μ κ°μ¬λ립λλ€. μ΄μ λν΄ λλ¨ν κ°μ¬ν©λλ€!
μ¬μ λ°ν μ μμΈ
System.NotSupportedException: 컬λ μ
μ ν 'System.Collections.Generic.Dictionary`2[System.Int32,System.String]'μ΄(κ°) μ§μλμ§ μμ΅λλ€.
System.Text.Json.JsonClassInfo.GetElementTypeμμ(μ ν propertyType, μ ν parentType, MemberInfo memberInfo, JsonSerializerOptions μ΅μ
)
at System.Text.Json.JsonClassInfo.CreateProperty(Type μ μΈλPropertyType, μ ν runtimePropertyType, PropertyInfo propertyInfo, μ ν parentClassType, JsonSerializerOptions μ΅μ
)
System.Text.Json.JsonClassInfo.AddPropertyμμ(μ ν propertyType, PropertyInfo propertyInfo, μ ν classType, JsonSerializerOptions μ΅μ
)
System.Text.Json.JsonClassInfo.AddPolicyProperty(μ ν propertyType, JsonSerializerOptions μ΅μ
)
System.Text.Json.JsonClassInfo..ctorμμ(μ ν μ ν, JsonSerializerOptions μ΅μ
)
System.Text.Json.JsonSerializerOptions.GetOrAddClass(μ ν classType)μμ
System.Text.Json.WriteStackFrame.Initializeμμ(μ ν μ ν, JsonSerializerOptions μ΅μ
)
at System.Text.Json.JsonSerializer.WriteAsyncCore(Stream utf8Json, κ°μ²΄ κ°, μ ν μ ν, JsonSerializerOptions μ΅μ
, CancellationToken μ·¨μ ν ν°)
Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext 컨ν
μ€νΈ, Encoding selectedEncoding)
Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext 컨ν
μ€νΈ, Encoding selectedEncoding)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvokerμμ.
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvokerμμ.
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed 컨ν
μ€νΈ)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext TFilter,TFilterAsyncμμ
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()μμ
--- μμΈκ° λ°μν μ΄μ μμΉμ μ€ν μΆμ λ ---
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvokerμμ.
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvokerμμ.
Microsoft.AspNetCore.Routing.EndpointMiddlewareμμ.
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext 컨ν
μ€νΈ)μμ
Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext 컨ν
μ€νΈ)μμ
Microsoft.AspNetCore.Builder.Extensions.MapWhenMiddleware.Invoke(HttpContext 컨ν
μ€νΈ)μμ
Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)μμ
Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)μμ
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext 컨ν
μ€νΈ)
BadRequest λ°ν μ μμΈ
System.NotSupportedException: 컬λ μ
νμ 'Microsoft.AspNetCore.Mvc.SerializableError'κ° μ§μλμ§ μμ΅λλ€.
System.Text.Json.JsonClassInfo.GetElementTypeμμ(μ ν propertyType, μ ν parentType, MemberInfo memberInfo, JsonSerializerOptions μ΅μ
)
at System.Text.Json.JsonClassInfo.CreateProperty(Type μ μΈλPropertyType, μ ν runtimePropertyType, PropertyInfo propertyInfo, μ ν parentClassType, JsonSerializerOptions μ΅μ
)
System.Text.Json.JsonClassInfo.AddPropertyμμ(μ ν propertyType, PropertyInfo propertyInfo, μ ν classType, JsonSerializerOptions μ΅μ
)
System.Text.Json.JsonClassInfo.AddPolicyProperty(μ ν propertyType, JsonSerializerOptions μ΅μ
)
System.Text.Json.JsonClassInfo..ctorμμ(μ ν μ ν, JsonSerializerOptions μ΅μ
)
System.Text.Json.JsonSerializerOptions.GetOrAddClass(μ ν classType)μμ
System.Text.Json.WriteStackFrame.Initializeμμ(μ ν μ ν, JsonSerializerOptions μ΅μ
)
at System.Text.Json.JsonSerializer.WriteAsyncCore(Stream utf8Json, κ°μ²΄ κ°, μ ν μ ν, JsonSerializerOptions μ΅μ
, CancellationToken μ·¨μ ν ν°)
Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext 컨ν
μ€νΈ, Encoding selectedEncoding)
Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext 컨ν
μ€νΈ, Encoding selectedEncoding)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvokerμμ.
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvokerμμ.
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed 컨ν
μ€νΈ)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext TFilter,TFilterAsyncμμ
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()μμ
--- μμΈκ° λ°μν μ΄μ μμΉμ μ€ν μΆμ λ ---
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvokerμμ.
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvokerμμ.
Microsoft.AspNetCore.Routing.EndpointMiddlewareμμ.
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext 컨ν
μ€νΈ)μμ
Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext 컨ν
μ€νΈ)μμ
Microsoft.AspNetCore.Builder.Extensions.MapWhenMiddleware.Invoke(HttpContext 컨ν
μ€νΈ)μμ
Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)μμ
Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)μμ
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext 컨ν
μ€νΈ)
"μ§μλμ§ μλ μμΈ" μ€λ₯λ λͺ¨λ κΈ°λ³Έ μ 곡 μ§λ ¬ λ³νκΈ° λ΄μ μ ν μ¬νμ΄λ©° μλμ μΌλ‘ μ€κ³λ κ²μ λλ€(μ μ΄λ 3.0μμ μ 곡λλ κ²½μ°).
μ΄ μ§μμ μΈμ μΆκ°λλμ? μ΄κ²μ Json.net λ° κΈ°ν μ§λ ¬ λ³νκΈ°μμ μ μ λμ μ§μλμκΈ° λλ¬Έμ μ΄κ²μ΄ λ μ΄λμ μκΈ°λ₯Ό λ°λλλ€.
Json.netμ λ€μ μ¬μ©νλλ‘ μ νν μ μλ€λ μ¬μ€μ κ°μ¬λ립λλ€. μ΄μ λν΄ λλ¨ν κ°μ¬ν©λλ€!
vNext(λ°λΌμ 5.0) μ΄μμμ μ§μνκΈ° μν΄ μ°λ¦¬ λ μ΄λμ μλ μΌλ ¨μ μ§λ ¬ λ³νκΈ° κΈ°λ₯μ΄ μμΌλ©° μ¬μ©μ μ§μ μ¬μ μ§μμ΄ κ·Έ μ€ νλμ λλ€.
Asp.NET Web Apis, μ¬μ μ λ°νν λ NotSupportedExceptionκ³Ό ν¨κ» μ€ν¨ν©λλ€.
μ§λ ¬νν λ νμ¬ Dictionary<string, TValue>
λ§ μ§μλ©λλ€(μ¦, λ¬Έμμ΄μΈ TKey). κ·νμ μ¬μ μ μ§μλμ§ μλ <int, string>
μ
λλ€.
https://github.com/dotnet/corefx/blob/93d7aa1c1737b6da29d04b78557215e18eb786d4/src/System.Text.Json/tests/Serialization/DictionaryTests.cs#L385 -L390
@steveharter , @layomia - κ·Έ λμ μ¬κΈ°μ μ μ¬μ μΈ ν΄κ²° λ°©λ²μ΄ μμ΅λκΉ? 5.0μ© μ§λ ¬ λ³νκΈ° λ΄μμ λ¬Έμμ΄μ΄ μλ ν€ μ¬μ μ λν μ§μμ μΆκ°νλ €λ©΄ 무μμ΄ νμν©λκΉ?
System.NotSupportedException: 컬λ μ νμ 'Microsoft.AspNetCore.Mvc.SerializableError'κ° μ§μλμ§ μμ΅λλ€.
~ SerializableErrorμ κ°μ μ νμ λν μ§μμ μΆκ°νλ κ²μ λ΄ λ μ΄λμ μμμ΅λλ€. @pranavkm , @rynowak - μ¬κΈ°μ 컨ν
μ€νΈλ 무μμ
λκΉ? ModelStateDictionary
μ΅μνμ§ μμ΅λλ€. μ΄κ²μ΄ μ¬μ©μ μ μ λ³νκΈ°λ₯Ό μ¬μ©νμ¬ mvc μ체 λ΄μμ μ§μλ μ μμ΅λκΉ?~
νΈμ§: μ κ²½ μ°μ§ λ§μΈμ. μ΄λ―Έ μμ λμμ΅λλ€.
System.NotSupportedException: 컬λ μ νμ 'Microsoft.AspNetCore.Mvc.SerializableError'κ° μ§μλμ§ μμ΅λλ€.
μ΄κ²μ μλ €μ§ λ¬Έμ ( https://github.com/aspnet/AspNetCore/issues/11459) λ‘ μ΅κ·Όμ μμ λμμ΅λλ€(미리 보기 8μ μΌλΆλ‘): https://github.com/dotnet/corefx/pull/39001
@ahsonkhan λΉ λ₯Έ λ΅λ³ κ°μ¬ν©λλ€!
λ΄κ° μκ°ν λ ν€κ° λ¬Έμμ΄μ΄λΌλ "μ ν"μ μ€μ λ‘ μλ―Έκ° μμ΅λλ€. μ΄μ Json.netμ΄ ν€λ₯Ό λ¬Έμμ΄λ‘ μ¬μ©νμ¬ jsonμ μμ±νλ€λ κ²μ μμμ΅λλ€. μμ§λ ¬ννλ©΄ intλ₯Ό λ€μ μ»μ μ μμ΅λλ€. λ―Έλμ λ¬Έμμ΄μ΄ μλ ν€λ₯Ό μ§μνλ κ²μ νμ€ν μ’κ² μ§λ§ μΌ μ€ν νΌλ μλλλ€.
μ’μ, μ§μλμ§ μλ Mvc.SerializableErrorκ° μμ λμλ€λ μμμ λ£κ² λμ΄ κΈ°μ©λλ€. Preview 8μ μΆμ λ μ§κ° μμλλμ§μ λν μμ΄λμ΄κ° μμ΅λκΉ? κ²μνκ³ λκ°λ₯Ό μ°ΎμΌλ €κ³ νμ§λ§ κ·Έκ²μ λν΄ μ무κ²λ λ³΄μ§ λͺ»νμ΅λλ€.
미리보기 8μ΄ λμ€λ©΄ .net core 3 json μ§λ ¬ν λΌμ΄λΈλ¬λ¦¬λ₯Ό λ€μ μλνκ² μ§λ§ μ§κΈμ Json.netμ κ³ μν΄μΌ ν©λλ€.
@steveharter , @layomia - κ·Έ λμ μ¬κΈ°μ μ μ¬μ μΈ ν΄κ²° λ°©λ²μ΄ μμ΅λκΉ? 5.0μ© μ§λ ¬ λ³νκΈ° λ΄μμ λ¬Έμμ΄μ΄ μλ ν€ μ¬μ μ λν μ§μμ μΆκ°νλ €λ©΄ 무μμ΄ νμν©λκΉ?
>
@ahsonkhan @willyt150 μ΄μ λν ν΄κ²° λ°©λ²μ JsonConverter<T>
λ₯Ό ꡬννλ μ¬μ©μ μ§μ λ³νκΈ°λ₯Ό μ¬μ©νλ κ²μ
λλ€. μ¬κΈ°μ T
λ Dictionary<int, string>
μ
λλ€.
λͺ κ°μ§ μλ https://github.com/dotnet/corefx/issues/36639#issue -429928740μ μ°Έμ‘°
Preview 8μ μΆμ λ μ§κ° μμλλμ§μ λν μμ΄λμ΄κ° μμ΅λκΉ?
μ΄λ¬ λ§μ―€.
μ΄μ λν΄ μ’ λ μκ°ν΄λ³΄λ©΄ κΈ°λ³Έμ μΌλ‘ μ§μνμ§ μμ μλ μκΈ° λλ¬Έμ λΉμ₯μ μ κ±°ν΄μΌ ν©λλ€.
@layomia κ°μ¬ν©λλ€. μ΄ν΄λ³΄κ² μ΅λλ€.
@ahsonkhanμκ² κ°μ¬λ립λλ€. μμ μ¬νμ΄ λμ€κΈ°λ₯Ό κΈ°λν©λλ€!
@namseμμ (https://github.com/dotnet/corefx/issues/40404μμ):
μλ νμΈμ. μ μ ν€λ‘ Dictionaryλ₯Ό μ§λ ¬ννλ €κ³ νλ©΄ System.NotSupportedExceptionμ΄ λ°μν©λλ€.
Dictionaryμ
ToString
-able ν€κ° μλ Json μ§λ ¬νλ₯Ό μ§μνλ κ²μ΄ ν©λ¦¬μ μ΄λΌκ³ μκ°ν©λλ€. μλ₯Ό λ€μ΄, int λλ booleanμ λν΄ ToStringμ μ€ννλ©΄ "123" λλ "true"κ° λ°νλ©λλ€. λλ κ·Έ ν€κ°ToString
-able ν€λΌκ³ μκ°ν©λλ€.Verison
System.Text.Json Nuget λ²μ : 4.6.0-preview8.19405.3
μνΈ
var dictionary = new Dictionary<int, string> { [5] = "five" }; JsonSerializer.Serialize(dictionary);
μμλλ
"{"5": "five"}"
νμ§λ§ λ¬΄μ¨ μΌμ΄
μ€λ₯
System.NotSupportedException
μ¬μ€ Newtonsoft.Jsonμ System.Text.JsonμΌλ‘ λ³κ²½νλ©΄ νΈνμ± λ¬Έμ κ° μμ΅λλ€. κ·Έλ€μ λ΄κ° μμν λλ‘ λ¬Έμμ΄μ λ°νν©λλ€. System.Text.Jsonμ΄ νΈνλ νμλ μλ€κ³ μκ°νμ§λ§... μμμ£ ?
IDictionary<TKey, TValue>
λν μ§λ ¬ν λ° μμ§λ ¬νλ₯Ό λͺ¨λ μ§μνλ λ³νκΈ°λ₯Ό ꡬννμ΅λλ€. μ¬κΈ°μ TKey
μλ TKey Parse(string)
μ μ λ©μλκ° μμ΅λλ€.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace JsonDictionaryConverter
{
sealed class JsonNonStringKeyDictionaryConverter<TKey, TValue> : JsonConverter<IDictionary<TKey, TValue>>
{
public override IDictionary<TKey, TValue> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var convertedType = typeof(Dictionary<,>)
.MakeGenericType(typeof(string), typeToConvert.GenericTypeArguments[1]);
var value = JsonSerializer.Deserialize(ref reader, convertedType, options);
var instance = (Dictionary<TKey, TValue>)Activator.CreateInstance(
typeToConvert,
BindingFlags.Instance | BindingFlags.Public,
null,
null,
CultureInfo.CurrentCulture);
var enumerator = (IEnumerator)convertedType.GetMethod("GetEnumerator")!.Invoke(value, null);
var parse = typeof(TKey).GetMethod("Parse", 0, BindingFlags.Public | BindingFlags.Static, null, CallingConventions.Any, new[] { typeof(string) }, null);
if (parse == null) throw new NotSupportedException($"{typeof(TKey)} as TKey in IDictionary<TKey, TValue> is not supported.");
while (enumerator.MoveNext())
{
var element = (KeyValuePair<string?, TValue>)enumerator.Current;
instance.Add((TKey)parse.Invoke(null, new[] { element.Key }), element.Value);
}
return instance;
}
public override void Write(Utf8JsonWriter writer, IDictionary<TKey, TValue> value, JsonSerializerOptions options)
{
var convertedDictionary = new Dictionary<string?, TValue>(value.Count);
foreach (var (k, v) in value) convertedDictionary[k?.ToString()] = v;
JsonSerializer.Serialize(writer, convertedDictionary, options);
convertedDictionary.Clear();
}
}
sealed class JsonNonStringKeyDictionaryConverterFactory : JsonConverterFactory
{
public override bool CanConvert(Type typeToConvert)
{
if (!typeToConvert.IsGenericType) return false;
if (typeToConvert.GenericTypeArguments[0] == typeof(string)) return false;
return typeToConvert.GetInterface("IDictionary") != null;
}
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
{
var converterType = typeof(JsonNonStringKeyDictionaryConverter<,>)
.MakeGenericType(typeToConvert.GenericTypeArguments[0], typeToConvert.GenericTypeArguments[1]);
var converter = (JsonConverter)Activator.CreateInstance(
converterType,
BindingFlags.Instance | BindingFlags.Public,
null,
null,
CultureInfo.CurrentCulture);
return converter;
}
}
}
μν:
class Entity
{
public string Value { get; set; }
}
class TestClass
{
public Dictionary<int, Entity> IntKey { get; set; }
public Dictionary<float, Entity> FloatKey { get; set; }
public Dictionary<double, Entity> DoubleKey { get; set; }
public Dictionary<DateTime, Entity> DateTimeKey { get; set; }
public Dictionary<string, Entity> StringKey { get; set; }
}
class Program
{
static void Main(string[] args)
{
var options = new JsonSerializerOptions();
options.Converters.Add(new JsonNonStringKeyDictionaryConverterFactory());
var x = new TestClass
{
IntKey = new Dictionary<int, Entity> { [1] = new Entity { Value = "test" } },
FloatKey = new Dictionary<float, Entity> { [1.3f] = new Entity { Value = "test" } },
DoubleKey = new Dictionary<double, Entity> { [1.35] = new Entity { Value = "test" } },
DateTimeKey = new Dictionary<DateTime, Entity> { [DateTime.Now] = new Entity { Value = "test" } },
StringKey = new Dictionary<string, Entity> { ["test"] = new Entity { Value = "test" } }
};
var value = JsonSerializer.Serialize(x, options);
Console.WriteLine(value);
var obj = JsonSerializer.Deserialize<TestClass>(value, options);
Console.WriteLine(JsonSerializer.Serialize(obj, options));
}
}
κ²°κ³Ό:
{"IntKey":{"1":{"Value":"test"}},"FloatKey":{"1.3":{"Value":"test"}},"DoubleKey":{"1.35":{"Value":"test"}},"DateTimeKey":{"8/25/2019 6:47:48 PM":{"Value":"test"}},"StringKey":{"test":{"Value":"test"}}}
{"IntKey":{"1":{"Value":"test"}},"FloatKey":{"1.3":{"Value":"test"}},"DoubleKey":{"1.35":{"Value":"test"}},"DateTimeKey":{"8/25/2019 6:47:48 PM":{"Value":"test"}},"StringKey":{"test":{"Value":"test"}}}
κ·Έλ¬λ System.Text.Jsonμ΄ λ΄λΆ μ ν Dictionary<int, int>
νμ©νμ§ μκΈ° λλ¬Έμ Dictionary<int, Dictionary<int, int>>
μ κ°μ μ€μ²© μ¬μ μ μ§λ ¬νν μ μμ΅λλ€. λ²κ·ΈλΌκ³ μκ°ν©λλ€.
κ·Έλ¬λ μ¬μ ν Dictionaryμ κ°μ μ€μ²© μ¬μ μ μ§λ ¬νν μ μμ΅λλ€.
> System.Text.Jsonμ λ΄λΆ μ ν μ¬μ μ νμ©νμ§ μκΈ° λλ¬Έμ . λ²κ·ΈλΌκ³ μκ°ν©λλ€.
<string, x>
λ§ μ§μνλ κ²μ v3.0μ©μΌλ‘ μ 곡νκΈ° μν λ²μ μΆμλ‘ μΈν΄ μλμ μΌλ‘ μ€κ³λ κ²μ
λλ€. 3.0 릴리μ€λ κ°μ₯ μΌλ°μ μΈ μλ리μ€κ° μ§μλλ μ΅μνμ μ€ν κ°λ₯ν μ νμ
λλ€.
@steveharter μ μ΄λ μ¬μ© κ°λ₯ν λ³νκΈ°κ° μμ λ
.net core 3.1μμ μ΄λ₯Ό μ§μν κ³νμ΄ μμ΅λκΉ?
μ κ· μ΄λ―Όμμ κ²½μ° μμ ν΄κ²°μ±
μ Newtonsoft.Json
λ‘ λλ리λ κ²μ
λλ€.
Microsoft.AspNetCore.Mvc.NewtonsoftJson
ν¨ν€μ§ μ°Έμ‘°λ₯Ό μΆκ°ν©λλ€..AddControllers()
/ .AddMvc()
λλ λ€λ₯Έ μ‘°ν© λ°λ‘ λ€μ .AddNewtonsoftJson()
μΆκ°ν©λλ€.@steveharter μ μ΄λ μ¬μ© κ°λ₯ν λ³νκΈ°κ° μμ λ
μ, κ·Έκ²μ μ λΉν μ§μ μ λλ€. μλ§λ μ°λ¦¬λ 3.1μμ μ΄ μ νμ μ κ±°ν μ μμ κ²μ λλ€. cc @layomia
λν μ€λλ μ¬μ μμλ ν€κ° λ¬Έμμ΄μ΄κΈ° λλ¬Έμ κ°λ₯ν μμ±μ²λΌ μ§λ ¬νλλ€λ μ μ λͺ νν νκΈ° μν΄μμ λλ€. λ¬Έμμ΄μ΄ μλ ν€λ₯Ό μ§μνλ©΄ μμκ° KeyValuePairλ‘ μ§λ ¬νλ©λλ€.
μ΄λ°, 3.0μΌλ‘ μ κ·Έλ μ΄λν μ§νμ μ΄ λ¬Έμ κ° λ°μνμ΅λλ€.
AddNewtonsoftJsonμΌλ‘ newton ν¨ν€μ§λ₯Ό μ€μΉν΄μΌ νμ΅λλ€.
https://github.com/dotnet/corefx/issues/41345μ @israellot μμ
var dictionary = new Dictionary<int, int>() { [0] = 1 }; var serialized = System.Text.Json.JsonSerializer.Serialize(dictionary);
μ΄ κ°λ¨ν μ§λ ¬νλ int ν€λ₯Ό λ¬Έμμ΄λ‘ μ§λ ¬ννμ¬ μ΄μ κΈ°λ³Έ Newtonsoft json λΌμ΄λΈλ¬λ¦¬μμ μ μ²λ¦¬λ©λλ€. System.Text.Jsonμμ μ§μλμ§ μλ μμΈκ° λ°μν©λλ€.
@israellot , @unruledboy λ° κΈ°ν μ€λ λμ κ²½μ° μλ리μ€μμ κ°μ²΄ λͺ¨λΈμ μ μ ν€κ° μλ μ¬μ μ΄ νμν μ΄μ μ μ΄λ₯Ό Dictionary<string, TValue>
λ³κ²½νλ©΄ μλνμ§ μλ μ΄μ μ λν μΈλΆ μ 보λ₯Ό μ 곡ν μ μμ΅λκΉ? μꡬ μ¬νμ μμ§νκ³ μμ μ¬νμ λκΈ°λ₯Ό λΆμ¬νλ λ° λμμ΄ λλ λͺ κ°μ§ μ¬μ©λ²μ λ³΄κ³ μΆμ΅λλ€.
μ΄μ¨λ λ¬Έμμ΄λ‘ μ§λ ¬νλλ―λ‘ κΈ°λ³Έ μ¬μ μ λμ int32 ν€λ₯Ό μ¬μ©νλ €λ μλ리μ€λ₯Ό μ΄ν΄ν μ μμ΅λλ€.
@ahsonkhan ν΅μ¬ λκΈ°λ νΈνμ±μ΄λΌκ³ μκ°ν©λλ€.
μ΄μ κΈ°λ³Έ μ§λ ¬ λ³νκΈ°λ NewtonsoftμμΌλ―λ‘ μ¬μ©μλ μμ ν΄λμ€λ₯Ό μ§λ ¬ν λ° μμ§λ ¬ννλ κΈ°λ₯μ μμ‘΄νμ¬ μ 체 λͺ¨λΈμ μμ±νμ μ μμ΅λλ€. 2.Xμμ 3.0μΌλ‘ λ§μ΄κ·Έλ μ΄μ
νλ©΄ λ°νμ μ λΉνΈνμ±λ§ μ μ μμΌλ―λ‘ μ΄μ μ‘°μ©ν μ£Όμ λ³κ²½ μ¬νμ΄ λ°μν©λλ€.
λ§μ μλ리μ€κ° μ μ μ ν΅ν μ μ‘μΌλ‘ jsonμ μ¬μ©νλ κ²κ³Ό κ΄λ ¨μ΄ μλ€κ³ μκ°ν©λλ€. μ΄ κ²½μ° λλ©μΈ λͺ¨λΈμ μ¬μ μΌ μ μμ΅λλ€.
μ§λ ¬ λ³νκΈ°λ₯Ό μ격ν μ΄ν΄λ³΄λ©΄ μ¬μ μ λ¬Έμμ΄ ν€λ₯Ό μ¬μ©νλλ‘ μ ννλ κ²μ κ°λ₯ν μ μΌν json ννμ΄λ―λ‘ λ
Όλ¦¬μ μ
λλ€. κ·Έλ¬λ μ§λ ¬ λ³νκΈ°κ° μμ© νλ‘κ·Έλ¨μμ μν μ νλ€λ μ μ κ³ λ €νλ©΄ κ°λ₯ν ν λ§μ λ§μ°°μ μ κ±°νλ κ²μ΄ κ°μ₯ μ’μ΅λλ€.
λ²μ λ μ΄λΈμ μΌλΆκ° json νμΌμ ν΅ν΄ μ 곡λλ κ³³μμ μμ± μ€μΈ μμ νλ‘κ·Έλ¨μμ μ΄ λ¬Έμ μ λΆλͺμ³€μ΅λλ€.
λ μ΄λΈ λΆλΆμλ λ μ΄λΈ λΆλΆμ μ½μ
ν μ μλ μΈλ±μ€λ₯Ό μ§μ νλ ν€κ° μμ΅λλ€. μ΄κ²μ ν€κ° μ«μ κ°μμ μλ―Έν©λλ€. μλ₯Ό λ€μ΄
{
"parts" : {
"1" : "alpha",
"3" : "beta"
}
}
Newtonsoftλ₯Ό μ¬μ©νλ©΄ jsonμ Dictionary<int, string>
λ¬Έμ μμ΄ μμ§λ ¬νν μ μμ΅λλ€. System.Text.JsonμΌλ‘ λ³νν ν μ§λ ¬νμ μ€ν¨νμ΅λλ€.
λ΄ μμ μ DictionaryConverter λ° DictionaryConverterλ₯Ό λ§λ€μ΄ μ΄ λ¬Έμ λ₯Ό ν΄κ²°νμ΅λλ€.
λν λ¬Έμμ΄μμ μ μλ₯Ό μμ§λ ¬νν μ μλ κ°λ¨ν λ³νκΈ° λ₯Ό λ§λ€μμ΅λλ€.
κ·Έλ° λ€μ μ§λ ¬ λ³νκΈ° μ΅μ μ ν΅ν΄ λ±λ‘λ©λλ€. https://github.com/Kieranties/SimpleVersion/blob/master/src/SimpleVersion.Core/Serialization/Serializer.cs#L22
μ΄λ¬ν λ³κ²½μ ν΅ν΄ μ¬μ μ ν€λ₯Ό λ¬Έμμ΄λ‘ μ§μ μ½λ λμ μμ§λ ¬νν μ μμ΅λλ€. μ΄κ²μ μ§λ ¬νλ₯Ό μν΄ λ±λ‘λ μ체 λ³νκΈ°λ₯Ό κ°μ§ μ μλ μμ μ ν(μ: κ³ μ ν€λ‘ μ§λ ¬νλ μ μλ μ΄κ±°ν/μ ν/μ ν λ±)μ΄ λ ν€μ λν μ§μμ μΆκ°λ‘ μ½λλ€.
곡μμ μΌλ‘ ν μ€νΈνμ§λ μμμ§λ§ νμ¬ κ°λ° λ΄μμ μ΄κ²μ΄ λ¬Έμ λ₯Ό ν΄κ²°ν κ² κ°μ΅λλ€.
TKey
λν Dictionary<TKey,TValue>
TKey
λ₯Ό μ²λ¦¬ν μ μλ μ¬μ©μ μ§μ λ³νκΈ°κ° μμ±λμ§ μλλ‘ νλ λͺ¨λ μ νμ μ κ±°νκΈ° μν΄ 3.1μ λν λ§μΌμ€ν€μ μ€μ ν©λλ€.
μ λ°μ΄νΈ: 3.0μμ μλνλ μνμ μΆκ°νμ΅λλ€. μμμ λ³΄κ³ λ μ€μ²© μ¬μ κ³Ό κ°μ λ¬Έμ λ₯Ό λ°κ²¬νμ§ λͺ»νμ΅λλ€.
μνμλ λ κ°μ§ JSON νμμ΄ μ¬μ©λ©λλ€.
{"1":"val1","2":"val2"}
TKey
λ λ¬Έμμ΄μ΄ μλμ§λ§ {"1":"val1","2":"val2"}
μ
λλ€.TryParse
λ©μλμ μμ‘΄ν©λλ€. v3.0μ κ²½μ° TryParse
λ©μλλ TKey
λν΄ λ€λ₯Ό μ μκ³ μ 곡ν΄μΌ νλ λ¬Έν μ€μ μ΄ μκΈ° λλ¬Έμ μΌλ°νλ TKey
μ λν μ§μμ μ 곡νλ κ²μ΄ κ°λ₯νμ§ μμ΅λλ€ TryParse
(μΌλ°μ μΌλ‘ λΆλ³). λ°λΌμ μλ μνμ λ¨μΌ TKey
μ νμ λν κ²μ
λλ€.Sample Dictionary<int, string>
. μ΄κ²μ TValue
== string
λν κ°λ¨ν μμ
λλ€.Sample Dictionary<Guid, TValue>
. μ΄κ²μ λͺ¨λ TValue
μ²λ¦¬ν μ μμ΅λλ€.Sample Dictionary<TKey, TValue> where TKey is Enum
. μ΄κ±°νμ κ²½μ° μ΄κ²μ λͺ¨λ TValue
μ²λ¦¬ν μ μμ΅λλ€.[{"Key":1,"Value":"val1"},{"Key":2,"Value":"val2"}]
Sample Dictionary<int, string>
. μ΄κ²μ TValue
== string
λν κ°λ¨ν μμ
λλ€.Sample Dictionary<TKey, TValue>
. μ νμ΄ κΈ°λ³Έμ μΌλ‘ JSONμΌλ‘ νμλκ³ TryParse
νμνμ§ μκΈ° λλ¬Έμ μ΄κ²μ λͺ¨λ TKey
λ° TValue
λ₯Ό μ²λ¦¬ν μ μμ΅λλ€.μ΄λ¬ν μνμ΄ λ§μ‘±μ€λ¬μ΄ κ²½μ° μ¬μ©μ μ§μ λ³νκΈ°κ° νμνμ§ μμ κΈ°λ³Έ μ 곡 μ§μμ μ 곡νλμ§ μ¬λΆλ₯Ό λ ΌμνκΈ° μν΄ μ΄ λ¬Έμ λ₯Ό 5.0μΌλ‘ λ³κ²½νκ² μ΅λλ€.
κ³ λ €λ₯Ό μν΄ λ§μΌμ€ν€μ 5.0μΌλ‘ μ€μ ν©λλ€(μμ μ μ€ νλλΌλ κΈ°λ³Έμ μΌλ‘ μλν΄μΌ νλ κ²½μ°).
λν μμ§λ ¬νλ μΌλ° κ°μ²΄ μ νμ μΌλ°(κΈ°λ³Έ?) μ νμ΄ μλ JsonDocumentμ 맀ννλ κ²μΌλ‘ 보μ λλ€.
μμ:
string test = "[{\"id\":86,\"name\":\"test\"}]";
var SystemTextJson = System.Text.Json.JsonSerializer.Deserialize<List<Dictionary<string, object>>>(test);
var NewtonSoftJson = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(test);
SystemTextJson[0]["id"]λ λ€μκ³Ό κ°μ΄ νμλ©λλ€. ValueKind = Number: "86"
NewtonSoftJson[0]["id"]λ λ€μκ³Ό κ°μ΄ νμλ©λλ€. 86
@steveharter ν΄λΉ λ³νκΈ°κ° μλ μ΄κ±°ν ν€ μ¬μ μ λ€μκ³Ό κ°μ΄ μ§λ ¬νλ©λλ€.
{
"Stuff": [
{
"Key": 1,
"Value": "String"
},
{
"Key": 3,
"Value": "String"
},
{
"Key": 2,
"Value": "String"
}
]
}
JSON.NETμ λλΆλΆμ μ¬λλ€μ΄ μμν κ²μ΄λΌκ³ κ°μ νλ κ²μ μ 곡νμ§λ§:
{
"Stuff": {
"Item1": "String",
"Item2": "String",
"Item3": "String"
}
λν μμ§λ ¬νλ μΌλ° κ°μ²΄ μ νμ μΌλ°(κΈ°λ³Έ?) μ νμ΄ μλ JsonDocumentμ 맀ννλ κ²μΌλ‘ 보μ λλ€.
μ, κ·Έκ²μ μλλ κ²μ λλ€. https://github.com/dotnet/corefx/issues/38713 μ°Έμ‘°
@steveharter ν΄λΉ λ³νκΈ°κ° μλ μ΄κ±°ν ν€ μ¬μ μ λ€μκ³Ό κ°μ΄ μ§λ ¬νλ©λλ€.
{ "λ΄μ©": [ { "ν€": 1, "κ°": "λ¬Έμμ΄" }, { "ν€": 3, "κ°": "λ¬Έμμ΄" }, { "ν€": 2, "κ°": " λ" } ] }
JSON.NETμ λλΆλΆμ μ¬λλ€μ΄ μμν κ²μ΄λΌκ³ κ°μ νλ κ²μ μ 곡νμ§λ§:
{ "λ΄μ©": { "νλͺ©1": "λ¬Έμμ΄", "νλͺ©2": "λ¬Έμμ΄", "νλͺ©3": "λ¬Έμμ΄" }
"μν μ¬μ "μ μ¬μ©νκ³ μλ€κ³ κ°μ ν©λλ€.
κ·Έλ, κ·Έκ±°μΌ. κ·Έλ¦¬κ³ μ μ’μ, λλ λΉμ μ΄ κ·Έκ²μ μΌλ° μ¬μ μ§λ ¬ λ³νκΈ°λ‘ μλ―Ένλ€κ³ μκ°νμ΅λλ€.
μ°λ¦¬κ° νμ¬ μ¬μ©νκ³ μλ μνμ΄ λ΄κ° μνλ κ²λ§νΌ λΉ λ₯΄μ§ μμ κ² κ°μμ μ¬μ© κ°λ₯ν κ²½μ° μ μνμ λ³΄κ³ μΆμ΅λλ€.
@roguecode λ€μμ Dictionary<TKey, TValue>
λν Enum μν μ
λλ€. μ¬κΈ°μ TKeyλ Enumμ΄κ³ KeyValuePair λμ "μμ±" JSON ꡬ문μ μ¬μ©ν©λλ€. λν μ΄ μ μνμ ν¬ν¨νλλ‘ μμ μν λͺ©λ‘μ μ
λ°μ΄νΈνμ΅λλ€.
μλ νμΈμ, λΉμ·νμ§λ§ λ€λ₯Έ κ²μ΄ μμ΅λλ€. λ€λ₯Έ κ³³μ λ³Ό μ μλμ§ μλ €μ£Όμ€ μ μλμ§ κΆκΈν©λλ€.
Newtonsoft.Json: 12.0.2
Microsoft.AspNetCore.Mvc.NewtonsoftJson: 3.0.0
3.0μΌλ‘ μ€ν μμ:
.AddMvc(mvcOptions => mvcOptions.EnableEndpointRouting = false)
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.AddNewtonsoftJson();
μ΄ problemDetails κ°μ²΄κ° μλ κ²½μ°:
// problemDetails has 2 extension items
{Microsoft.AspNetCore.Mvc.ValidationProblemDetails}
Detail: "Please refer to the 'errors' property for additional details."
Errors: Count = 1
Extensions: Count = 2
Instance: "/api/test/complex-binding-from-query"
Status: 400
Title: "One or more validation errors occurred."
Type: "https://tools.ietf.org/html/rfc7231#section-6.5.1"
2.2μμ Newtonsoft.Json.JsonConvert.SerializeObject(problemDetails)
μ€ννλ©΄
{"errors":{"Int":["The value 'a' is not valid for Int."]},"type":"https://tools.ietf.org/html/rfc7231#section-6.5.1","title":"One or more validation errors occurred.","status":400,"detail":"Please refer to the 'errors' property for additional details.","instance":"/api/test/complex-binding-from-query","traceId":"0HLQQ40AFBJNG","correlationId":"0HLQQ40AFBJNG"}
3.0μμλ λ€μμ λ°νν©λλ€.
{"Errors":{"param":["The value 'a' is not valid."]},"Type":"https://tools.ietf.org/html/rfc7231#section-6.5.1","Title":"One or more validation errors occurred.","Status":400,"Detail":"Please refer to the 'errors' property for additional details.","Instance":"/bad-request","Extensions":{"traceId":"|d0d40f80-48b6c9184401b0e1.","correlationId":"0HLQR10NSMRGD:00000009"}}
3.0 λ²μ μ§λ ¬ν λ¬Έμμ΄μλ IDictionaryκ° ν¬ν¨λ©λλ€.Extensions
μ΄λ©° 3.0μμ ν΄λΉ λ¬Έμμ΄μ μ¬λ°λ₯΄κ² μμ§λ ¬νν μ μμ΅λλ€. μ΄ μμ± μ΄λ¦μ 2.x λ²μ μμ μ μΈλ κ²μ λ³Ό μ μμ΅λλ€.
λ¬Έμ λ μλ μ½λμμ BadRequestObjectResult
μ¬μ©νμ¬ νν°μμ μλ΅μ΄ λ°νλ λ λ°μνλ 3.0 μ§λ ¬νμ
λλ€.
public sealed class ProblemDetailsResultFilterAttribute : Attribute, IAlwaysRunResultFilter
{
public void OnResultExecuting(ResultExecutingContext context)
{
context.Result = new BadRequestObjectResult(problemDetails);
}
}
..., λ°νλλ μλ΅ λ΄μ©μ 2.2 λ²μ κ³Ό λμΌν νμ( Extensions
μμ± μ΄λ¦ μ μΈ)μ΄λ―λ‘ Extensions
μμ±μ΄ λΉ μ»¬λ μ
μΌλ‘ μμ§λ ¬νλ©λλ€(μ¬μ© Newtonsoft.Json.JsonConvert.DeserializeObject<ValidationProblemDetails>()
)
μ¬ννΌ μ΄ μ§λ ¬νλ μ°λ¦¬κ° μμ§λ ¬ννλ €λ Newtonsoft λΌμ΄λΈλ¬λ¦¬μ λμΌν μ§λ ¬νλ₯Ό μ¬μ©νμ§ μμ΅λλ€.
κ³ λ €ν΄μ£Όμ μ κ°μ¬ν©λλ€!
λΉμ·νλ©΄μλ λ€λ₯Έκ² μμ΄μ
@ts46235 μ΄ λ¬Έμ λ νμ¬ λ¬Έμ μ λ€λ₯΄κΈ° λλ¬Έμ μ λ¬Έμ λ₯Ό μ΄μ΄ μ£Όμκ² μ΅λκΉ?
@ts46235 μ¬κΈ°μμ μ° λ€λ₯Έ λ¬Έμ ( https://github.com/aspnet/AspNetCore/issues/16618) μμ κ·νμ μ§λ¬Έμ λ΅λ³νμ΅λλ€
Core 3.1λ‘ μ λ°μ΄νΈλμμ§λ§ μ¬μ ν μμ λμ§ μμ
λ°©κΈ 3.1λ‘ μ κ·Έλ μ΄λνκ³ μ΄κ²μ λΆλͺμ³€μ΅λλ€. JSON.NETμΌλ‘ λμκ°κΈ° ... (GUID ν€ μ¬μ©)
λ·λ· μ½μ΄ 3.1
μ¬μ
λλ λ°©κΈ μ΄κ²μ μ³€κ³ λ€λ₯Έ μ¬λλ€μ΄ μ§μ νλ―μ΄ μ»΄νμΌ νμμλ μ΄κ²μ λ³Ό μ μκΈ° λλ¬Έμ 무μμ΄ μΉ¨λ¬΅μ μ νμ
λλ€. μ κ²½μ°μλ Dictionary<int, List<string>>
λ₯Ό μ§λ ¬ννκ³ μΆμ΅λλ€. μ΄κ²μ νΉλ³ν μ΄κ΅μ μ΄λΌκ³ μκ°νμ§ μμ΅λλ€.
κ·Έλ€μ κ·Έκ²μ κ³ μ³μΌ νμ§λ§ λλ μμ ν¬λ§·ν°, λ°μ΄λ리 ν¬λ§·ν° early newtsoft, μ¬μ μ μλ μ¬μ , μΈν°νμ΄μ€κ° μλ μ¬μ μ μ¬μ©ν΄λ μ΄ μκ°μ λͺ λ²μ΄κ³ λ€μ λ³΄κ² λ©λλ€. κ·Έλ€μ κ·Έκ²μ κ³ μ³μΌ νμ§λ§ λΉμ μ΄ λ¬Έμ λ₯Ό μνμ§ μλλ€λ©΄ μ¬λλ€μ λ¬Έμ λ₯Ό μꡬνλ μ§λ ¬ν κ³μ½μ μ¬μ κ³Ό κ°μ 볡μ‘ν κ°μ²΄λ₯Ό λμ΄μλ μ λ©λλ€. newtsoftλ μ¬λλ€μ λ§μ³€μ΅λλ€. μ΄κ²μ 맀ννκΈ° μν΄ μ§λ ¬ λ³νκΈ°μ μ¬μ©μ μ μμ μμ‘΄νκ³ μλ Dictionary count λ±μ λͺ¨λ κ³΅μ© μμ±μ μ΄ν΄λ³΄μμμ€.
λΆννλ C#μλ μμ± μ΄λ¦μ λν κ°λ¨ν μ νμ΄ μμΌλ―λ‘ μ¬μ μ΄ κ°μ μ μ©λ©λλ€. κ·Έλμ κ·Έλ₯ μ¬νλ€..
λ€μμ ν΄κ²° λ°©λ²μ΄μ§λ§ μμ ν μ루μ μ μλλλ€.
[JsonConverter(typeof(DictionaryConverter))]
public Dictionary<string, object> ExtraProperties { get; set; } = new Dictionary<string, object>();
public class DictionaryConverter : JsonConverter<Dictionary<string, object>>
{
public override Dictionary<string, object> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var dictionary = JsonSerializer.Deserialize<Dictionary<string, object>>(ref reader, options);
foreach (string key in dictionary.Keys.ToList())
{
if (dictionary[key] is JsonElement je)
{
dictionary[key] = Unwrap(je);
}
}
return dictionary;
}
public override void Write(Utf8JsonWriter writer, Dictionary<string, object> value, JsonSerializerOptions options)
=> JsonSerializer.Serialize(writer, value, options);
private static object Unwrap(JsonElement je)
{
return je.ValueKind switch
{
JsonValueKind.String => je.ToString(),
JsonValueKind.Number => je.TryGetInt64(out var l) ? l : je.GetDouble(),
JsonValueKind.True => true,
JsonValueKind.False => false,
JsonValueKind.Array => je.EnumerateArray().Select(Unwrap).ToList(),
JsonValueKind.Object => je.EnumerateObject().ToDictionary(x => x.Name, x => Unwrap(x.Value)),
_ => null
};
}
μλ§λ μλ¦¬μΌ λΌμ΄μ λ OOTBλ₯Ό μΆκ° ν μ μμ΅λλ€ μΌλ°μ μΈ μ ν (μ μΌλΆ), μμ λν μ§μ μ΄ λͺ©λ‘ , λν μ΄λ¬ν μ ν μ€ νλκ° .IsAssignableFrom(systemDotObjectInstance.GetType())
μ§μνκΈ° Dictionary<<ins i="7">object</ins>, V>
.
λ€μμ μ¬μ μμ λ¬Έμμ΄μ΄ μλ TKey
μ νμ λν μ§μμ μΆκ°νκΈ° μν μ μμ
λλ€.
https://github.com/dotnet/runtime/pull/32676
μ΄λ€ μκ°μ΄λ μ°λ € μ¬νμ΄ μμΌλ©΄ μλ €μ£Όμμμ€.
νΉν @Jozkee κ° μ¬μ ν€λ₯Ό μ§μν κ³νμΈ μ ν μΈνΈμ λν νΌλλ°±μ μ 곡νμΈμ. νΉν μ§μν΄μΌ ν λ€λ₯Έ μ νμ΄ νμν κ²½μ°(κΈ°λ³Έμ μΌλ‘ λͺ¨λ κΈ°λ³Έ μ 곡 κΈ°λ³Έ μ«μ μ ν, μ΄κ±°ν λ° κΈ°ν λͺ κ°μ§):
https://github.com/dotnet/runtime/blob/a5d96c0e280b56412d4614848f5ee3b1e0d7f216/src/libraries/System.Text.Json/docs/KeyConverter_spec.md#keyconverter
μ¬μ
@andrew-vdb, μμ κ°μ²΄ ν€μ μ§λ ¬ν μ§μμ κ³μ μ§μλμ§ μμ κ²μ λλ€. κ·Έλ¬λ κ°μ²΄ ν€μ λ°νμ μ νμ΄ "μλ‘ μ§μλλ" μ ν μ€ νλμΈ κ²½μ° κΈ°λ₯μ΄ μλ£λλ©΄ μ§λ ¬νκ° μλν©λλ€. κ·Έλ¬λ μμ§λ ¬νλ λ°μ€ν JsonElementλ‘ μ μ§λ©λλ€(λ€λ₯Έ λμμ μ ννκΈ° μν μ΄ κ΄λ ¨ λ¬Έμ κ° ν΄κ²°λ λκΉμ§): https://github.com/dotnet/runtime/issues/29960
@Jozkee TValue
λν΄ νμ±νλ μ νμ 무μμ
λκΉ? μλ§λ νμ¬ λ
립 μ€νν κ°μ²΄λ‘ μ§λ ¬νν μ μλ κ²μ 무μμ
λκΉ?
μλ§λ νμ¬ λ 립 μ€νν κ°μ²΄λ‘ μ§λ ¬νν μ μλ κ²μ 무μμ λκΉ?
μ.
https://docs.microsoft.com/en-gb/dotnet/standard/serialization/system-text-json-converters-how-to#support -dictionary-with-non-string-key
λν μμ§λ ¬νλ μΌλ° κ°μ²΄ μ νμ μΌλ°(κΈ°λ³Έ?) μ νμ΄ μλ JsonDocumentμ 맀ννλ κ²μΌλ‘ 보μ λλ€.
μμ:
string test = "[{\"id\":86,\"name\":\"test\"}]"; var SystemTextJson = System.Text.Json.JsonSerializer.Deserialize<List<Dictionary<string, object>>>(test); var NewtonSoftJson = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(test);
SystemTextJson[0]["id"]λ λ€μκ³Ό κ°μ΄ νμλ©λλ€. ValueKind = Number: "86"
NewtonSoftJson[0]["id"]λ λ€μκ³Ό κ°μ΄ νμλ©λλ€. 86
μΈκΈλ λͺ¨λ λ¬Έμ μ€μμ μ΄κ²μ΄ λλ₯Ό κ°μ₯ κ΄΄λ‘νλ λ¬Έμ μ
λλ€. λͺ©λ‘
3.0 릴리μ€λ κ°μ₯ μΌλ°μ μΈ μλ리μ€κ° μ§μλλ μ΅μνμ μ€ν κ°λ₯ν μ νμ λλ€.
λλ μ΄λ»κ² λͺ©λ‘
[// N objects
{"a":4},
{"b","Bla"},
]
μ΄κ²μ λν System.Text.JsonElementλ‘ μμ§λ ¬ννκΈ° λλ¬Έμ μ΄μ€(μ«μ) λ° λ¬Έμμ΄(λ¬Έμμ΄)μ΄ μμλ©λλ€.
λ²μ λ μ΄λΈμ μΌλΆκ° json νμΌμ ν΅ν΄ μ 곡λλ κ³³μμ μμ± μ€μΈ μμ νλ‘κ·Έλ¨μμ μ΄ λ¬Έμ μ λΆλͺμ³€μ΅λλ€.
λ μ΄λΈ λΆλΆμλ λ μ΄λΈ λΆλΆμ μ½μ ν μ μλ μΈλ±μ€λ₯Ό μ§μ νλ ν€κ° μμ΅λλ€. μ΄κ²μ ν€κ° μ«μ κ°μμ μλ―Έν©λλ€. μλ₯Ό λ€μ΄{ "parts" : { "1" : "alpha", "3" : "beta" } }
Newtonsoftλ₯Ό μ¬μ©νλ©΄ jsonμ
Dictionary<int, string>
λ¬Έμ μμ΄ μμ§λ ¬νν μ μμ΅λλ€. System.Text.JsonμΌλ‘ λ³νν ν μ§λ ¬νμ μ€ν¨νμ΅λλ€.λ΄ μμ μ DictionaryConverter λ° DictionaryConverterλ₯Ό λ§λ€μ΄ μ΄ λ¬Έμ λ₯Ό ν΄κ²°νμ΅λλ€.
.
λν λ¬Έμμ΄μμ μ μλ₯Ό μμ§λ ¬νν μ μλ κ°λ¨ν λ³νκΈ° λ₯Ό λ§λ€μμ΅λλ€.κ·Έλ° λ€μ μ§λ ¬ λ³νκΈ° μ΅μ μ ν΅ν΄ λ±λ‘λ©λλ€. https://github.com/Kieranties/SimpleVersion/blob/feature/netcore3/src/SimpleVersion.Core/Serialization/Serializer.cs#L20
μ΄λ¬ν λ³κ²½μ ν΅ν΄ μ¬μ μ ν€λ₯Ό λ¬Έμμ΄λ‘ μ§μ μ½λ λμ μμ§λ ¬νν μ μμ΅λλ€. μ΄κ²μ μ§λ ¬νλ₯Ό μν΄ λ±λ‘λ μ체 λ³νκΈ°λ₯Ό κ°μ§ μ μλ μμ μ ν(μ: κ³ μ ν€λ‘ μ§λ ¬νλ μ μλ μ΄κ±°ν/μ ν/μ ν λ±)μ΄ λ ν€μ λν μ§μμ μΆκ°λ‘ μ½λλ€.
곡μμ μΌλ‘ ν μ€νΈνμ§λ μμμ§λ§ νμ¬ κ°λ° λ΄μμ μ΄κ²μ΄ λ¬Έμ λ₯Ό ν΄κ²°ν κ² κ°μ΅λλ€.
μλ νμΈμ @Kieranties , github λ§ν¬ 404
μλ νμΈμ @Kieranties , github λ§ν¬ 404
@AirEssY μλ μ견μ λ§ν¬λ₯Ό μμ νμ΅λλ€. μ΄μ https://github.com/Kieranties/SimpleVersion/tree/master/src/SimpleVersion.Core/Serialization μμ λ§μ€ν°μ μλ€κ³ μκ°ν©λλ€.
μ¬μ μ΄ JavaScript 맡과 λμΌνλ©΄ λͺ¨λ (C#μΌλ‘ ννλλ JS μ ν)μ΄ νμ©λμ΄μΌ ν©λλ€.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
A Map's keys can be any value (including functions, objects, or any primitive).
JSμμ 맡μ μμ§λ ¬ννλ νμ€ μ κ·Ό λ°©μμ μλ λ€μκ³Ό κ°μ΅λλ€.
const countries = new Map(JSON.parse('[[1,"Bahamas (the)"],[2,"Bolivia (Plurinational State of)"]]'))
console.log(countries)
λ€μμ μμ±ν©λλ€.
Map(2) {
1 => 'Bahamas (the)',
2 => 'Bolivia (Plurinational State of)'
}
TL; DR: ν€λ₯Ό λ¬Έμμ΄λ‘ μ ννλ κ²μ JSμμ μ μλνμ§ μμ΅λλ€.
@Jozkee κ·Έλμ μ΄κ²μ .NET 5μμλ§ μ 곡λ©λκΉ μλλ©΄ 3.*μΌλ‘ λ€μ΄κ° κ²μ λκΉ?
@onionhammer .NET 5.0, λ€μ 미리보기(5.0 미리보기8)μμ κΈ°λ₯μ μ¬μ©ν΄ λ³Ό μλ μμ΅λλ€.
μ΄κ²μ 3.xλ‘ μ΄μν κ³νμ μμ΅λλ€.
asp net core 3.xμ© μ루μ :
var dic1 = new Dictionary<TKey, TValue>();
return Json(new { dic1 }); // does not work
var dic2 = from i in new Dictionary<TKey, TValue>() select new { i.Key, i.Value }
return Json(new { dic2 }); //works prety well
@verloka λ μνλ μΆλ ₯μ΄ μλλλ€.
@Jozkee κ·Έλμ μ΄κ²μ .NET 5μμλ§ μ 곡λ©λκΉ μλλ©΄ 3.*μΌλ‘ λ€μ΄κ° κ²μ λκΉ?
μ΄κ²μ 3.xλ‘ λ°±ν¬νΈλμ§ μμ§λ§ νλ‘μ νΈμμ System.Text.Json NuGet ν¨ν€μ§ λ₯Ό μ¬μ©νμ¬ .NET 5μ λͺ¨λ μλ‘μ΄ κΈ°λ₯μ μΆκ°ν μ μμ΅λλ€.
κ°μ₯ μ μ©ν λκΈ
μ κ· μ΄λ―Όμμ κ²½μ° μμ ν΄κ²°μ± μ
Newtonsoft.Json
λ‘ λλ리λ κ²μ λλ€.Microsoft.AspNetCore.Mvc.NewtonsoftJson
ν¨ν€μ§ μ°Έμ‘°λ₯Ό μΆκ°ν©λλ€..AddControllers()
/.AddMvc()
λλ λ€λ₯Έ μ‘°ν© λ°λ‘ λ€μ.AddNewtonsoftJson()
μΆκ°ν©λλ€.