JamesNK / Newtonsoft.Json

Json.NET is a popular high-performance JSON framework for .NET
https://www.newtonsoft.com/json
MIT License
10.73k stars 3.25k forks source link

If the type file is stored separately in a cs file, OnDeserialized is invalid #2817

Closed waleywu closed 1 year ago

waleywu commented 1 year ago

Source/destination types


// DirectoryAccount.cs
public class DirectoryAccount
{
    // normal deserialization
    public string DisplayName { get; set; }

    // these properties are set in OnDeserialized
    public string UserName { get; set; }
    public string Domain { get; set; }

    [JsonExtensionData]
    private IDictionary<string, JToken> _additionalData;

    [OnDeserialized]
    private void OnDeserialized(StreamingContext context)
    {
        // SAMAccountName is not deserialized to any property
        // and so it is added to the extension data dictionary
        string samAccountName = (string)_additionalData["SAMAccountName"];

        Domain = samAccountName.Split('\\')[0];
        UserName = samAccountName.Split('\\')[1];
    }

    public DirectoryAccount()
    {
        _additionalData = new Dictionary<string, JToken>();
    }
}
// test.cs
public void test()
{
     string json = @"{
  'DisplayName': 'John Smith',
  'SAMAccountName': 'contoso\\johns'
}";

DirectoryAccount account = JsonConvert.DeserializeObject<DirectoryAccount>(json);

Console.WriteLine(account.DisplayName);
}

Source/destination JSON

{
  'DisplayName': 'John Smith',
  'SAMAccountName': 'contoso\\johns'
}

Expected behavior

Actual behavior

Steps to reproduce

The DirectoryAccount type is stored in a separate file, then _additionalData.Count ==0. _additionalData.Count ==1 if it is and in the test.cs file,

// Your calls to Newtonsoft.Json here
elgonzo commented 1 year ago

If the type file is stored separately in a cs file, OnDeserialized is invalid

The DirectoryAccount type is stored in a separate file

What? I do not understand. What exactly do you mean?

Your problem is definitely not due to the source code being organized simply in different cs files. There must be more to it that you did not include in your problem description. Can you explain by giving a concrete and complete example that reproduces the problem you are having?

elgonzo commented 1 year ago

I rather suspect you included the wrong namespace(s) when writing your source code. Because both Newtonsoft.Json as well as System.Text.Json.Serialization namespaces provide a JsonExtensionDataAttribute type.

And i strongly suspect you included the System.Text.Json.Serialization namespace in your source code, therefore the wrong JsonExtensionDataAttribute is being used. Newtonsoft.Json only looks for its own JsonExtensionDataAttribute type contained in the Newtonsoft.Json namespace. Therefore, make sure you do not import/use the System.Text.Json.Serialization namespace in your DirectoryAccount.cs source code.

waleywu commented 1 year ago

Thank you for reminding me. What you said is correct

I rather suspect you included the wrong namespace(s) when writing your source code. Because both Newtonsoft.Json as well as System.Text.Json.Serialization namespaces provide a JsonExtensionDataAttribute type.

And i strongly suspect you included the System.Text.Json.Serialization namespace in your source code, therefore the wrong JsonExtensionDataAttribute is being used. Newtonsoft.Json only looks for its own JsonExtensionDataAttribute type contained in the Newtonsoft.Json namespace. Therefore, make sure you do not import/use the System.Text.Json.Serialization namespace in your DirectoryAccount.cs source code.