5

I am have issue mapping a json coming from a different project api to my model Customer for the property public Dictionary<string, List<CustomerAddress>> CustomerAddress{ get; set; }

I have a ISerializationBinder defined for my json settings as follows

public class KnownTypesBinder : ISerializationBinder
{
    public IList<Type> KnownTypes { get; set; }

    public string TypeFormat { get; private set; }

    public KnownTypesBinder(string typeFormat)
    {
        TypeFormat = typeFormat;
    }
    public void BindToName(Type serializedType, out string assemblyName, out string typeName)
    {
        assemblyName = null;
        typeName = serializedType.Name;
    }

    public Type BindToType(string assemblyName, string typeName)
    {                 
             resolvedTypeName = string.Format(TypeFormat, typeName.Split('.').Last());              

        return Type.GetType(resolvedTypeName, true);
    }
}

And my deserialization code using the above binder is as follows:

var settings = new JsonSerializerSettings
{
    TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple,
    TypeNameHandling = TypeNameHandling.All,
    
    SerializationBinder = new KnownTypesBinder("CustomerWeb.API.Models.{0}, CustomerWeb.API, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
    {
        KnownTypes = new List<Type>
        {
            typeof(CustomerProducts),                                     
            typeof(Dictionary<string,Customer>),
        }
    }
};

var jsonToObject = JsonConvert.DeserializeObject<Customer>(strStream, settings)

My other properties with Customer class are bing mapped. Only the dictionary type are failing . Can someplease guide meon this.

Errors Research: The below is the type of my project dictionary

System.Collections.Generic.Dictionary2[[System.String, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Collections.Generic.List1[[CustomerWeb.API.Models.CustomerAddress, CustomerWeb.API, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e

The below one is the type coming in from Json object from another api

System.Collections.Generic.Dictionary2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Collections.Generic.List1[[Customer.CustomerWeb.Common.CustomerAddress, Customer.CustomerWeb.Common.V4, Version=9.0.0.0, Culture=neutral, PublicKeyToken=f291d57f641e84e4]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]

I could identify the mismatch but how to handle it. I have no control on the settings of the Json serialization of the api coming from different project.

Sample Json :

{
"$id": "1",
"$type": "Customer.CustomerWeb.Common.CustomerRecommendation, Customer.CustomerWeb.Common.V4, Version=9.0.0.0, Culture=neutral, PublicKeyToken=f291d57f641e84e4",
"Addr1": "Cust1",
"CustomerAddress": {
    "$id": "41",
    "$type": "System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Collections.Generic.List`1[[Customer.CustomerWeb.Common.CustomerAddress, Customer.CustomerWeb.Common.V4, Version=9.0.0.0, Culture=neutral, PublicKeyToken=f291d57f641e84e4]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
    "Items": {
        "$id": "42",
        "$type": "System.Collections.Generic.List`1[[Customer.CustomerWeb.Common.CustomerAddress, Customer.CustomerWeb.Common.V4, Version=9.0.0.0, Culture=neutral, PublicKeyToken=f291d57f641e84e4]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
        "$values": [
            {
                "$id": "43",
                "$type": "Customer.CustomerWeb.Common.CustomerAddress, Customer.CustomerWeb.Common.V4, Version=9.0.0.0, Culture=neutral, PublicKeyToken=f291d57f641e84e4",
                "CustomerID": 268541064,
                "ApplicationID": 110296837,
                "ProductID": 1,
                "ProductCode": 1,
                "Amount": 1000.00000,
                "AmountPercent": 2.98,
                "AppliedValueType": 1,                                   
                "Id": 811760147,
                "RealId": 811760147,
                "DirtyProperties": {
                    "$id": "46",
                    "$type": "System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[Drive.Framework.DirtyProperty, OriginationFramework, Version=9.0.0.0, Culture=neutral, PublicKeyToken=f291d57f641e84e4]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
                },
                "IsDirty": false,
                "IsNew": false,
                "IsDeleted": false,
                "ModifiedDate": "2020-05-28T09:01:27.033",
                "CreatedDate": "2020-05-28T09:01:27.033",
                "ModifiedByID": 0,
                "CreatedByID": 0,
                "DeactivationDate": null,
                "ActivationDate": null,
                "SerializationTracking": null
            }
        ]
    },
    }
    }
Ravio
  • 115
  • 9
  • The problem is that the open generic class `Dictionary` resides in DLLs with different names in .Net core and .Net framework, hence the inconsistency. One way to handle that would be to detect and fix the .Net framework type names in the incoming `assemblyName` and `typeName` strings. But if you only need to deserialize, you could just discard the type name information for dictionaries. To do that see [Deserialization of JSON from previous data model with Custom Converters fails when deserializing collections of Interfaces](https://stackoverflow.com/a/35493529/3744182). – dbc Jul 24 '20 at 18:55
  • Can you please give me an example for fixing the assemblyName and typeName.. Have been trying the Json converter for ignoring types..but no luck yet in my case. – Ravio Jul 24 '20 at 19:46
  • Can you share a [mcve] showing your current JSON and classes? ... you do realize that your `KnownTypesBinder` **completely ignores the known types** and just does `Type.GetType(resolvedTypeName, true)` on the incoming type name, don't you? So it isn't a `KnownTypesBinder` at all. The `KnownTypesBinder` in the [Json.NET docs](https://www.newtonsoft.com/json/help/html/SerializeSerializationBinder.htm) does use the known types. – dbc Jul 24 '20 at 20:04
  • Yes dbc.. its a misnomer in my case. Will change the KnownTypesBinder. – Ravio Jul 24 '20 at 20:23
  • Updated with sample Json. – Ravio Jul 24 '20 at 20:58

0 Answers0