역직렬화 중 JSON.Net 무시 속성
클래스는 다음과 같이 설정되어 있습니다.
public class Foo
{
public string string1 { get; set; }
public string string2 { get; set; }
public string string3 { get; set; }
}
Json을 사용하고 있습니다.Net: 다음 Json 응답을 역직렬화합니다.
[
{
"number1": 1,
"number2": 12345678901234567890,
"number3": 3
},
{
"number1": 9,
"number2": 12345678901234567890,
"number3": 8
}
]
역직렬화 코드:
string json = @"[
{
""number1"": 1,
""number2"": 12345678901234567890,
""number3"": 3
},
{
""number1"": 9,
""number2"": 12345678901234567890,
""number3"": 8
}
]"
List<Foo> foos = JsonConvert.DeserializeObject<List<Foo>>(json);
의 값number2
1을 넘다Int64
그 값을 취득하는 것은 별로 신경 쓰지 않습니다.캐스트 할 수 있는 방법이 있을까요?number2
속성을 문자열에 저장할지, 아니면 역직렬화 중에 완전히 무시할지.
를 추가해 보았습니다.[JsonConverter(typeof(string))]
의 탓으로 돌리다string2
다음 오류를 수신합니다.Error creating System.String
설정도 시도했습니다.typeof(decimal)
.
저도 써봤어요.[JsonIgnore]
하지만 소용없어요.
사용할 수 있습니다.MissingMemberHandling
의 특성JsonSerializerSettings
물건.
사용 예:
var jsonSerializerSettings = new JsonSerializerSettings();
jsonSerializerSettings.MissingMemberHandling = MissingMemberHandling.Ignore;
JsonConvert.DeserializeObject<YourClass>(jsonResponse, jsonSerializerSettings);
자세한 것은 이쪽.
이 문제는 해결 방법이 부족하지만 수동으로 json을 로드하는 방법을 만들 수 있습니다.자동 디시리얼라이저 없이 로드하기에는 데이터가 너무 많은 경우 원하지 않는 노드를 삭제하십시오.이게 좀 느리긴 한데.
public static List<Foo> FromJson(string input) {
var json = JToken.Parse(input);
json["key"].Remove();
var foo = JsonConvert.DeserializeObject<List<Foo>>(json.ToString());
}
이 문제는 흥미로운 문제인데, 이에 대한 더 나은 해결책을 가진 사람이 있는지 궁금합니다.
다음은 Newtonsoft Json이 선호하는 속성 무시 방법입니다. http://james.newtonking.com/json/help/index.html?topic=html/ReducingSerializedJSONSize.htm에 따라 클래스를 수정할 필요가 없습니다.
이것은 EF 또는 Linq2Sql의 느린 참조 속성을 무시하는 데 사용됩니다.
public class DynamicContractResolver : DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties(Type type,
MemberSerialization memberSerialization)
{
Func<Type,bool> includeProperty = t => t.IsValueType || t.Namespace.StartsWith("System") && t.Namespace.StartsWith("System.Data")==false;
IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization);
var allProperties = properties.Select (p => new{p.PropertyName,Including=includeProperty(p.PropertyType), p.PropertyType});//.Dump("props");
var warnProperties=allProperties.Where (a =>a.Including && a.PropertyType.IsValueType==false && a.PropertyType.Name.IsIgnoreCaseMatch("String")==false) ;
//linq pad debugging helper
//var propertyTypesSerializing= allProperties.Where (p => p.Including).Select (p => p.PropertyType).Distinct().OrderBy (p => p.Name).Dump();
if(warnProperties.Any())
{
//LinqPad helper
//Util.Highlight(warnProperties.ToArray()).Dump("warning flag raised, aborting");
throw new ArgumentOutOfRangeException();
}
properties = properties.Where(p =>includeProperty(p.PropertyType)).ToList();
return properties;
}
}
모든..Dump()
콜은 linqpad 디버깅도우미일 뿐 메서드콜은 필요 없습니다.
사용 예:
var inactives = from am in Aspnet_Memberships
join mm in Member_members on am.UserId equals mm.Member_guid
where mm.Is_active==false && mm.Org_id==1
select new{am,mm};
//inactives.Take(4).ToArray().Dump();
var serialized = JsonConvert.SerializeObject(
inactives.Skip(1).Select(i => i.mm).First(),
new JsonSerializerSettings()
{
ContractResolver = new DynamicContractResolver(),
PreserveReferencesHandling = PreserveReferencesHandling.None,
ReferenceLoopHandling= ReferenceLoopHandling.Ignore
});
//.Dump();
@Maslow의 솔루션과 마찬가지로 다른 범용 "무시"를 사용할 수 있습니다.
var jsonResolver = new IgnorableSerializerContractResolver();
// ignore your specific property
jsonResolver.Ignore(typeof(Foo), "string2");
// ignore single datatype
jsonResolver.Ignore(typeof(System.Data.Objects.DataClasses.EntityObject));
var jsonSettings = new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore, ContractResolver = jsonResolver };
이 코드는 나에게 마법처럼 작용했다.
using System.Reflection;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
public class PropertyRenameAndIgnoreSerializerContractResolver : DefaultContractResolver
{
private readonly Dictionary<Type, HashSet<string>> _ignores;
private readonly Dictionary<Type, Dictionary<string, string>> _renames;
public PropertyRenameAndIgnoreSerializerContractResolver()
{
_ignores = new Dictionary<Type, HashSet<string>>();
_renames = new Dictionary<Type, Dictionary<string, string>>();
}
public void IgnoreProperty(Type type, params string[] jsonPropertyNames)
{
if (!_ignores.ContainsKey(type))
_ignores[type] = new HashSet<string>();
foreach (var prop in jsonPropertyNames)
_ignores[type].Add(prop);
}
public void RenameProperty(Type type, string propertyName, string newJsonPropertyName)
{
if (!_renames.ContainsKey(type))
_renames[type] = new Dictionary<string, string>();
_renames[type][propertyName] = newJsonPropertyName;
}
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
if (IsIgnored(property.DeclaringType, property.PropertyName))
{
property.ShouldSerialize = i => false;
property.Ignored = true;
}
if (IsRenamed(property.DeclaringType, property.PropertyName, out var newJsonPropertyName))
property.PropertyName = newJsonPropertyName;
return property;
}
private bool IsIgnored(Type type, string jsonPropertyName)
{
if (!_ignores.ContainsKey(type))
return false;
return _ignores[type].Contains(jsonPropertyName);
}
private bool IsRenamed(Type type, string jsonPropertyName, out string newJsonPropertyName)
{
Dictionary<string, string> renames;
if (!_renames.TryGetValue(type, out renames) || !renames.TryGetValue(jsonPropertyName, out newJsonPropertyName))
{
newJsonPropertyName = null;
return false;
}
return true;
}
}
//Foo의 number2를 무시하는 예
public class Foo
{
public string number1 { get; set; }
public string number2 { get; set; }
public string number3 { get; set; }
}
string Foojson = @"[
{
""number1"": 1,
""number2"": 12345678901234567890,
""number3"": 3
},
{
""number1"": 9,
""number2"": 12345678901234567890,
""number3"": 8
}
]";
var jsonResolverFoo = new PropertyRenameAndIgnoreSerializerContractResolver();
jsonResolverFoo.IgnoreProperty(typeof(Foo), "number2");
var serializerSettingsFoo = new JsonSerializerSettings();
serializerSettingsFoo.ContractResolver = jsonResolverFoo;
var deserializedJsonFoo = JsonConvert.DeserializeObject<List<Foo>>(Foojson, serializerSettingsFoo);
/* 리소스 링크: https://blog.rsuter.com/advanced-newtonsoft-json-dynamically-rename-or-ignore-properties-without-changing-the-serialized-class/ */
drzaus 답변 추가:를 사용할 수 있습니다.DefaultContractResolver
그는 …을 제안했다.한창일 때CreateProperty
사용하다property.Ignored = true;
대신property.ShouldSerialize
, 당신이 통과했을 때, 그것은 좋다.JsonSerializerSettings
에게DeserializeObject
기능 또는SerializeObject
기능.
대체 수단
ResponseAttribute에 모델 파라미터 또는 문자열 파라미터가 있는 경우
public class ResponseAttribute : Attribute { }
public class ModelItem
{
[Response]
public Guid Id { get; set; }
}
코드
public class CustomJsonSerializer : JsonSerializerSettings
{
public CustomJsonSerializer()
{
ContractResolver = new CustomContractResolver();
}
public CustomJsonSerializer(params string[] members)
{
ContractResolver = new CustomContractResolver(members);
}
public class CustomContractResolver : DefaultContractResolver
{
public string[] Members { get; set; }
public CustomContractResolver(params string[] _members)
{
Members = _members;
}
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty property = base.CreateProperty(member, memberSerialization);
if (Members?.Length > 0)
property.ShouldSerialize = instance => { return Members.Contains(member.Name); };
else
property.ShouldSerialize = instance => { return member.GetCustomAttribute<ResponseAttribute>() != null; };
return property;
}
}
}
사용;
return new JsonResult(model, new CustomJsonSerializer());
또는
return new JsonResult(model, new CustomJsonSerializer("Id","Test","Test2"));
비슷한 것을 발견했습니다만, 클래스에는 리스트<>와 사전<>이 포함되어 있어, JSON 파일에 격납되어 있는 것에 의해서 덮어쓰면 안 됩니다.스크래치 오브젝트에 데이터를 로드하고 필요한 아이템을 꺼내는 것이 당시 찾을 수 있었던 다른 방법보다 쉬웠습니다.
그래서 이 예에서는 이런 거...
public class Foo
{
public string string1 { get; set; }
public string string2 { get; set; }
public string string3 { get; set; }
}
List<Foo> foos = new List<Foo>();
List<Foo> tmp= JsonConvert.DeserializeObject<List<Foo>>(json);
foreach(Foo item in tmp)
{
foos.string1 = tmp.string1;
foos.string3 = tmp.string3;
}
https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-how-to?pivots=dotnet-6-0에 따르면
클래스에 표시되지 않는 JSON 속성은 무시됩니다.
언급URL : https://stackoverflow.com/questions/12754463/json-net-ignore-property-during-deserialization
'programing' 카테고리의 다른 글
Woocommerce ph 코드 get_price_html() (0) | 2023.02.26 |
---|---|
요소가 표시되지 않음 오류(요소를 클릭할 수 없음) (0) | 2023.02.26 |
Moment.js 와 ReactJS (ES6) (0) | 2023.02.26 |
Play 2.2 라이브러리로 밀봉된 특성을 위한 노이즈 프리 JSON 형식 (0) | 2023.02.26 |
Python: 간단한 설정/구성 파일을 저장하는 방법은 무엇입니까? (0) | 2023.02.26 |