Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSON.NET - exclude properties of a specific type at runtime

I'm wondering how to exclude/strip certain properties of given type(s) (or collections of those) from being serialized using Json.NET library? I tried to write my own contract resolver (inheriting from DefaultContractResolver) with no luck.

I know that I could be done using DataAnnotations, decorating the excluded properties with ScriptIgnoreAttribute, but it's not applicable in my scenario. The objects serialized can be virtually anything, so I don't know which properties to exclude at design-time. I know only the types of properties that should not be serialized.

It looks like a rather simple task, but unfortunately I couldn't find a decent solution anywhere...

BTW - I'm not bound to Json.NET library - if it can easily be done with default/other .NET JSON serializers it'd be an equally good solution for me.

UPDATE

The properties has to be excluded before trying to serialize them. Why?

Basically, the types of objects I'm receiving and serializing can have dynamic properties of type inheriting from IDynamicMetaObjectProvider. I'm not going to describe all the details, but the DynamicMetaObject returned from GetMetaObject method of these objects doesn't have DynamicMetaObject.GetDynamicMemberNames method implemented (throws NotImplementedException...). Summarizing - the problem is those objects (I need to exclude) doesn't allow to enumerate their properties, what Json.NET serializer tries to do behind the scenes. I always end up with NotImplementedException being thrown.

like image 284
Piotr Szmyd Avatar asked May 27 '11 00:05

Piotr Szmyd


People also ask

How do I ignore individual properties in JSON output?

To ignore individual properties, use the [JsonIgnore] attribute. Here's an example type to serialize and JSON output: You can specify conditional exclusion by setting the [JsonIgnore] attribute's Condition property. The JsonIgnoreCondition enum provides the following options: Always - The property is always ignored.

How to name a property in a JSON object?

The name of the property has to be in the JSON form, not the C# form. So maybe the serializer uses camel case and you need to specify it as "stateName"? But the final object is a class derived IBaseObject generic type.

How to solve the issue of unwanted json JSON?

To solve the issue of unwanted JSON Json.NET has a range of built in options to fine tune what gets written from a serialized object. JsonIgnoreAttribute and DataMemberAttribute. By default Json.NET will include all of a classes public properties and fields in the JSON it creates.

Can I ignore or rename serialized JSON properties?

This article describes how to implement a custom contract resolver, so that you can ignore or rename serialized JSON properties where the serialization happens and without changing the serialized classes.


2 Answers

I have tried both the WCF JSON serialization as well as the System.Web.Script.Serialization.JavaScriptSerializer. I have found if you want solid control of the serialization process and do not want to be bound by attributes and hacks to make things work, the JavaScriptSerializer is the way to go. It is included in the .NET stack and allows you to create and register JavaScriptConverter subclasses to perform custom serialization of types.

The only restriction I have found that may cause you a problem is that you cannot easily register a converter to convert all subclasses of Object (aka, one converter to rule them all). You really need to have knowledge of common base classes or preregister the set of types up front by scanning an assembly. However, property serialization is entirely left up to you, so you can decide using simple reflection which properties to serialize and how.

Plus, the default serialization is much much much better for JSON than the WCF approach. By default, all types are serializable without attributes, enums serialize by name, string-key dictionaries serialize as JSON objects, lists serialize as arrays, etc. But for obvious reasons, such as circular trees, even the default behavior needs assistance from time to time.

In my case, I was supporting a client-API that did not exactly match the server class structure, and we wanted a much simpler JSON syntax that was easy on the eyes, and the JavaScriptSerializer did the trick every time. Just let me know if you need some code samples to get started.

like image 169
Jamie Thomas Avatar answered Sep 21 '22 04:09

Jamie Thomas


Create your own contract resolver, override the method that creates the properties for an object and then filter the results to only include those that you want.

like image 28
James Newton-King Avatar answered Sep 19 '22 04:09

James Newton-King