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.

4
  • 2
    This really looks like the XY problem. What are you trying to do? Commented Jan 3, 2016 at 11:53
  • If you as developer cannot identify which concrete object it is, how do you expect a framework such as JSON.NET to be able to? Commented Jan 3, 2016 at 11:54
  • But it showing the full namespace of that class -- so what is the problem? From your description, it sounds as though Json.NET is successfully serializing and deserializing the type information. Commented Jan 3, 2016 at 14:10
  • I have updated the question Commented Jan 3, 2016 at 14:24

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

Comments

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.