Json.Net deserialization constructor vs property rules

I was looking for a serialization (de) problem with the following class using Json.Net:

public class CoinsWithdrawn
{
    public DateTimeOffset WithdrawlDate { get; private set; }
    public Dictionary<CoinType, int> NumberOfCoinsByType { get; private set; }

    public CoinsWithdrawn(DateTimeOffset withdrawDate, Dictionary<CoinType, int> numberOfCoinsByType)
    {
        WithdrawlDate = withdrawDate;
        NumberOfCoinsByType = numberOfCoinsByType;
    }
}

The problem is that the argument to the removeDate constructor is named differently from the name of the WithDrawlDate property. Matching the names (even ignoring the case) fixed the problem.

However, I wanted to understand this a little better, so I returned the code and tested it after both setters became available. This also fixed the problem.

Finally, I switched from auto-properties to properties using the support fields so that I can completely debug and see what is actually happening:

public class CoinsWithdrawn
{
    private DateTimeOffset _withdrawlDate;
    private Dictionary<CoinType, int> _numberOfCoinsByType;

    public DateTimeOffset WithdrawlDate
    {
        get { return _withdrawlDate; }
        set { _withdrawlDate = value; }
    }

    public Dictionary<CoinType, int> NumberOfCoinsByType
    {
        get { return _numberOfCoinsByType; }
        set { _numberOfCoinsByType = value; }
    }

    public CoinsWithdrawn(DateTimeOffset withdrawDate, Dictionary<CoinType, int> numberOfCoinsByType)
    {
        WithdrawlDate = withdrawDate;
        NumberOfCoinsByType = numberOfCoinsByType;
    }
}

I tried this with and without the default constructor (the code shows the default constructor).

: , .

: , Setter SetDrawlDate. SetOfCoinsByType .

, , ( - , , , ), , , . p >

? - / ?

+4
1

, , ( - , , , ), , , . ?

, . , . JsonSerializerInternalReader CreateObjectUsingCreatorWithParameters, , . .

ResolvePropertyAndCreatorValues JSON, . , 1 remainingPropertyValues. , . ( ) .

IDictionary<JsonProperty, object> propertyValues = 
    ResolvePropertyAndCreatorValues(contract, containerProperty, reader, objectType, out extensionData);

object[] creatorParameterValues = new object[contract.CreatorParameters.Count];
IDictionary<JsonProperty, object> remainingPropertyValues = new Dictionary<JsonProperty, object>();

foreach (KeyValuePair<JsonProperty, object> propertyValue in propertyValues)
{
    JsonProperty property = propertyValue.Key;

    JsonProperty matchingCreatorParameter;
    if (contract.CreatorParameters.Contains(property))
    {
        matchingCreatorParameter = property;
    }
    else
    {
        // check to see if a parameter with the same name as the underlying property name exists and match to that
        matchingCreatorParameter = contract.CreatorParameters.ForgivingCaseSensitiveFind(p => p.PropertyName, property.UnderlyingName);
    }

    if (matchingCreatorParameter != null)
    {
        int i = contract.CreatorParameters.IndexOf(matchingCreatorParameter);
        creatorParameterValues[i] = propertyValue.Value;
    }
    else
    {
        remainingPropertyValues.Add(propertyValue);
    }

    ...
} 
...

object createdObject = creator(creatorParameterValues);

...

1 - , , , , . ForgivingCaseSensitiveFind, .

- / ?

. , .

+2

Source: https://habr.com/ru/post/1611470/


All Articles