1
public class MyClass
{ 
    public object BidAutoObject { get; set; }
    public bool IsApplied { get; set; }
}

I have a class like above and I am creating the Json string from the above Class object. Property "BidAutoObject " is of type "object". The object may be "CxDays" or "AMPM". It is setting dynamically. I am using newtonsoft.JsonConvert.SerializeObject to serialize the C# object to Json string. The outpout of Json serialization is like

"BidAutoObject": {
    "IsSun": true,
    "IsMon": false,
    "IsTue": true,
    "IsWed": true,
    "IsThu": false,
    "IsFri": true,
    "IsSat": true
}

So I couldn't identify whether "BidAutoObject type is "CxDays" or "AMPM" from the above json string. how can I add the type information during the serialization process. Do I need to add any attribute to "BidAutoObject "?

public class CxDays
{
    public bool IsSun { get; set; }
    public bool IsMon { get; set; }
    public bool IsTue { get; set; }
}

public class AMPM
{
   public bool AM { get; set; }
   public bool PM { get; set; }
   public bool MIX { get; set; }
}

Instead of ""BidAutoObject": in the Json string, I need the class object name such as "CxDays" or "AMPM" in the json string. We have one option using "Jsonserializer setting" .When we set TypeNameHandling = TypeNameHandling.Auto - this will add a $type property ONLY for instances where the declared type (i.e. Base) does not match the instance type (i.e. Derived). But it showing the full namespace of that class.Now I want to show only the class name in the Json string instead of full name space.

Roshil K
  • 2,583
  • 28
  • 38

2 Answers2

1

I guess what you are looking for is the TypeNameHandling in the JsonSerializerSettings which you need to add for de- and serialization. Just set it to TypeNameHandling.Auto which will add a type property to the json for instances which have a type not equal to the declared type.

Manuel Zelenka
  • 1,616
  • 2
  • 12
  • 26
0

If you simply don't want the assembly name and namespace name to appear in the JSON for some reason (why?), you can create your own custom subclass of DefaultSerializationBinder and then set it in JsonSerializerSettings.Binder:

public class DefaultAssemblyBinder : DefaultSerializationBinder
{
    public string DefaultAssemblyName { get; private set; }
    public string DefaultNamespaceName { get; private set; }

    public DefaultAssemblyBinder(string defaultAssemblyName, string defaultNamespaceName)
    {
        this.DefaultAssemblyName = defaultAssemblyName;
        this.DefaultNamespaceName = defaultNamespaceName;
    }

    public override Type BindToType(string assemblyName, string typeName)
    {
        if (!string.IsNullOrEmpty(DefaultAssemblyName))
        {
            if (string.IsNullOrEmpty(assemblyName))
                assemblyName = DefaultAssemblyName;
        }
        if (!string.IsNullOrEmpty(DefaultNamespaceName))
        {
            if (typeName != null && !typeName.Contains("."))
                typeName = DefaultNamespaceName + "." + typeName;
        }
        return base.BindToType(assemblyName, typeName);
    }

    public override void BindToName(Type serializedType, out string assemblyName, out string typeName)
    {
        base.BindToName(serializedType, out assemblyName, out typeName);
        if (!string.IsNullOrEmpty(DefaultAssemblyName) && assemblyName != null)
            if (assemblyName == DefaultAssemblyName)
                assemblyName = null;
        if (!string.IsNullOrEmpty(DefaultNamespaceName) && typeName != null)
        {
            int index = typeName.LastIndexOf('.');
            if (index < 0)
                throw new JsonSerializationException(string.Format("Type {0} does not exist in any namespace, but a default namespace {1} has been set", serializedType.FullName, DefaultNamespaceName));
            if (index == DefaultNamespaceName.Length && string.Compare(DefaultNamespaceName, 0, typeName, 0, index, StringComparison.Ordinal) == 0)
                typeName = typeName.Substring(index + 1);
        }
    }
}

And then, later:

        var test = new MyClass { IsApplied = true, BidAutoObject = new CxDays { IsMon = false, IsSun = true, IsTue = false } };

        var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto, Binder = new DefaultAssemblyBinder(typeof(MyClass).Assembly.FullName, typeof(MyClass).Namespace) };
        var json = JsonConvert.SerializeObject(test, Formatting.Indented, settings);
        Console.WriteLine(json);

Creates the following JSON:

{
  "BidAutoObject": {
    "$type": "CxDays",
    "IsSun": true,
    "IsMon": false,
    "IsTue": false
  },
  "IsApplied": true
}

Prototype fiddle.

For another custom binder example, see Custom SerializationBinder from the documentation.

dbc
  • 104,963
  • 20
  • 228
  • 340