속성 뒤의 지원 필드에 숨겨져있을 때 사전의 직렬화 / 비 직렬화에 이상한 문제가 발생했습니다.
다음은 Fiddle입니다 : https://dotnetfiddle.net/RFZEur
최종 결과 :
public class SanityChecks
{
private readonly ITestOutputHelper _testOutputHelper;
public SanityChecks(ITestOutputHelper testOutputHelper)
{
_testOutputHelper = testOutputHelper;
}
public class TestClass
{
[JsonIgnore]
public Dictionary<int,string> _prvList = new Dictionary<int, string>();
public IEnumerable<string> ListValues
{
get => _prvList.Select(p=> p.Value).ToList();
set
{
var valArr = value.ToArray();
for (var x = 0; x < valArr.Length; x++)
{
_prvList.Add(x,valArr[x]);
}
}
}
}
[Fact]
public void SanityCheck_CanDeserialize()
{
var assumption = "{\"ListValues\":[\"TestValue\",\"AAA\"]}";
var actual = JsonConvert.DeserializeObject<TestClass>(assumption);
Assert.Equal(2, actual._prvList.Count());
Assert.Equal(2, actual.ListValues.Count());
}
[Fact]
public void SanityCheck_CanSerialize()
{
var assumption = new TestClass() { ListValues = new[] { "TestValue", "AAA" } };
var actualSerialized = JsonConvert.SerializeObject(assumption);
_testOutputHelper.WriteLine(actualSerialized);
Assert.Equal("{\"ListValues\":[\"TestValue\",\"AAA\"]}", actualSerialized);
}
[Fact]
public void SanityCheck_CanDeserializeFromSerialized()
{
var assumption = new TestClass() { ListValues = new[] { "TestValue", "AAA" } };
var actualSerialized = JsonConvert.SerializeObject(assumption);
_testOutputHelper.WriteLine(actualSerialized);
var actualDeserialized = JsonConvert.DeserializeObject<TestClass>(actualSerialized);
Assert.Equal(2, actualDeserialized._prvList.Count());
var actualDeserializedSerialized = JsonConvert.SerializeObject(actualDeserialized);
_testOutputHelper.WriteLine(actualDeserializedSerialized);
Assert.Equal(actualSerialized, actualDeserializedSerialized);
}
}
이 결과를 검색하는 방법에 대한 조언이 있으면 열려 있습니다. 테스트 목적으로 XUnit을 사용하고 있지만 바이올린은 콘솔 응용 프로그램을 만들기 위해 약간의 수정으로 아래 테스트를 빠르게 구현합니다.
ISerializable
객체 구현을 시도했지만 동일한 문제가 발생했습니다.
주목할만한 이상한 점 : 내부에서 Get 절을 제거IEnumerable
하면 역 직렬화가 작동합니다 (직렬화가 더 이상 작동하지 않음).
편집 : 추가 명확성을 위해 문자열 목록으로 직렬화 할 int, string 쌍의 매핑이 필요하며 int, string 쌍의 모음으로 직렬화 해제 할 수 있도록 동일한 직렬화 된 버전이 필요합니다.
Fiddle의 경우 : 예외가 발생해서는 안됩니다. XUnit의 경우 : 모든 테스트를 통과해야합니다.
ListValues
deserialization 후 열거 형이 비어있는 이유 는 다음과 같은 요인 때문입니다.
ListValues
경우 먼저 접근 자를 호출하고 기존 목록을 찾은 다음 계속해서 JSON에서 채 웁니다.ListValues
자는 매번 동일한 목록 인스턴스를 반환하지 않습니다. 항상 _prvList
지원 필드 에서 새 인스턴스를 만듭니다 .결과적으로 deserialization 중에 발생하는 작업은 다음과 같습니다.
ListValues
접근 자를 호출 하여 사전에서 만든 새 빈 목록을 반환합니다.TestClass
인스턴스에 이미 목록에 대한 참조가 있다고 가정 하므로 mutator를 호출하지 않습니다).ListValues
접근 자를 호출 하면 사전에서 다시 생성 된 새로운 빈 목록을 반환합니다.ObjectCreationHandling
설정을 로 설정하여 serializer의 동작을 변경할 수 있습니다 Replace
. 역 직렬화 중에이 설정을 적용하면 테스트를 통과 할 수 있습니다. 여기 바이올린 .
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다