C# JsonConvert using the default converter instead of the custom converter












4














I have a class as follows that has a custom JsonConverter:



[JsonConverter(typeof(TheShapeSerializer))]
public class TheShape : IShape {
//....
}


I cannot change the class. The way the custom serializer works is not appropriate for my needs.



Is there a way to serialize an instance of TheShape using the default serializer instead of TheShapeSerializer?



Along the same lines, is there a way to have multiple converters that can be selected at serialization time based on a given condition?










share|improve this question
























  • You could try using another converter when directly calling serialize/deserialize var json = JsonConvert.SerializeObject(obj, new MyCustomConverter()) That way you have greater control over the process.
    – Nkosi
    Nov 20 at 21:01












  • This is an interesting question. I am checking to see if my suggested comment is viable and not seeing anyone with similar issues.
    – Nkosi
    Nov 20 at 21:37






  • 1




    JsonConverter applied using attributes supersedes JsonConverter applied via settings. From the docs: The priority of which JsonConverter is used is member attribute, then class attribute, and finally any converters passed to the JsonSerializer.. You'll need to use a custom contract resolver.
    – dbc
    Nov 20 at 21:40






  • 1




    @dbc that is a good find in the docs. I was unaware of that.
    – Nkosi
    Nov 20 at 21:45
















4














I have a class as follows that has a custom JsonConverter:



[JsonConverter(typeof(TheShapeSerializer))]
public class TheShape : IShape {
//....
}


I cannot change the class. The way the custom serializer works is not appropriate for my needs.



Is there a way to serialize an instance of TheShape using the default serializer instead of TheShapeSerializer?



Along the same lines, is there a way to have multiple converters that can be selected at serialization time based on a given condition?










share|improve this question
























  • You could try using another converter when directly calling serialize/deserialize var json = JsonConvert.SerializeObject(obj, new MyCustomConverter()) That way you have greater control over the process.
    – Nkosi
    Nov 20 at 21:01












  • This is an interesting question. I am checking to see if my suggested comment is viable and not seeing anyone with similar issues.
    – Nkosi
    Nov 20 at 21:37






  • 1




    JsonConverter applied using attributes supersedes JsonConverter applied via settings. From the docs: The priority of which JsonConverter is used is member attribute, then class attribute, and finally any converters passed to the JsonSerializer.. You'll need to use a custom contract resolver.
    – dbc
    Nov 20 at 21:40






  • 1




    @dbc that is a good find in the docs. I was unaware of that.
    – Nkosi
    Nov 20 at 21:45














4












4








4


0





I have a class as follows that has a custom JsonConverter:



[JsonConverter(typeof(TheShapeSerializer))]
public class TheShape : IShape {
//....
}


I cannot change the class. The way the custom serializer works is not appropriate for my needs.



Is there a way to serialize an instance of TheShape using the default serializer instead of TheShapeSerializer?



Along the same lines, is there a way to have multiple converters that can be selected at serialization time based on a given condition?










share|improve this question















I have a class as follows that has a custom JsonConverter:



[JsonConverter(typeof(TheShapeSerializer))]
public class TheShape : IShape {
//....
}


I cannot change the class. The way the custom serializer works is not appropriate for my needs.



Is there a way to serialize an instance of TheShape using the default serializer instead of TheShapeSerializer?



Along the same lines, is there a way to have multiple converters that can be selected at serialization time based on a given condition?







c# json.net






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 20 at 23:21









dbc

53.2k869121




53.2k869121










asked Nov 20 at 20:42









isaac.hazan

1,81442659




1,81442659












  • You could try using another converter when directly calling serialize/deserialize var json = JsonConvert.SerializeObject(obj, new MyCustomConverter()) That way you have greater control over the process.
    – Nkosi
    Nov 20 at 21:01












  • This is an interesting question. I am checking to see if my suggested comment is viable and not seeing anyone with similar issues.
    – Nkosi
    Nov 20 at 21:37






  • 1




    JsonConverter applied using attributes supersedes JsonConverter applied via settings. From the docs: The priority of which JsonConverter is used is member attribute, then class attribute, and finally any converters passed to the JsonSerializer.. You'll need to use a custom contract resolver.
    – dbc
    Nov 20 at 21:40






  • 1




    @dbc that is a good find in the docs. I was unaware of that.
    – Nkosi
    Nov 20 at 21:45


















  • You could try using another converter when directly calling serialize/deserialize var json = JsonConvert.SerializeObject(obj, new MyCustomConverter()) That way you have greater control over the process.
    – Nkosi
    Nov 20 at 21:01












  • This is an interesting question. I am checking to see if my suggested comment is viable and not seeing anyone with similar issues.
    – Nkosi
    Nov 20 at 21:37






  • 1




    JsonConverter applied using attributes supersedes JsonConverter applied via settings. From the docs: The priority of which JsonConverter is used is member attribute, then class attribute, and finally any converters passed to the JsonSerializer.. You'll need to use a custom contract resolver.
    – dbc
    Nov 20 at 21:40






  • 1




    @dbc that is a good find in the docs. I was unaware of that.
    – Nkosi
    Nov 20 at 21:45
















You could try using another converter when directly calling serialize/deserialize var json = JsonConvert.SerializeObject(obj, new MyCustomConverter()) That way you have greater control over the process.
– Nkosi
Nov 20 at 21:01






You could try using another converter when directly calling serialize/deserialize var json = JsonConvert.SerializeObject(obj, new MyCustomConverter()) That way you have greater control over the process.
– Nkosi
Nov 20 at 21:01














This is an interesting question. I am checking to see if my suggested comment is viable and not seeing anyone with similar issues.
– Nkosi
Nov 20 at 21:37




This is an interesting question. I am checking to see if my suggested comment is viable and not seeing anyone with similar issues.
– Nkosi
Nov 20 at 21:37




1




1




JsonConverter applied using attributes supersedes JsonConverter applied via settings. From the docs: The priority of which JsonConverter is used is member attribute, then class attribute, and finally any converters passed to the JsonSerializer.. You'll need to use a custom contract resolver.
– dbc
Nov 20 at 21:40




JsonConverter applied using attributes supersedes JsonConverter applied via settings. From the docs: The priority of which JsonConverter is used is member attribute, then class attribute, and finally any converters passed to the JsonSerializer.. You'll need to use a custom contract resolver.
– dbc
Nov 20 at 21:40




1




1




@dbc that is a good find in the docs. I was unaware of that.
– Nkosi
Nov 20 at 21:45




@dbc that is a good find in the docs. I was unaware of that.
– Nkosi
Nov 20 at 21:45












1 Answer
1






active

oldest

votes


















2














The order in which JsonConverters are selected is documented as follows:




The priority of which JsonConverter is used is member attribute, then class attribute, and finally any converters passed to the JsonSerializer.




Thus you cannot disable a JsonConverter applied via JsonConverterAttribute using JsonSerializerSettings.Converters. Instead, you have the following options.



Firstly, if your TheShape is being referred to directly by some type you control, you could grab NoConverter from this answer to Selectively use default JSON converter and apply it to the referring members using JsonConverterAttribute or JsonPropertyAttribute.ItemConverterType, e.g. as follows:



public class ShapeContainer
{
[JsonConverter(typeof(NoConverter))]
public TheShape Shape { get; set; }

[JsonProperty(ItemConverterType = typeof(NoConverter))]
public List<TheShape> Shapes { get; set; }
}


Now NoConverter will supersede TheShapeSerializer for the properties where it is applied, and cause Json.NET to fall back on default serialization.



Secondly, if you cannot add member attributes to types where TheShape is used, you could create a custom contract resolver that overrides DefaultContractResolver.ResolveContractConverter and returns null for TheShape. First define the following contract resolver:



public class ConverterDisablingContractResolver : DefaultContractResolver
{
readonly HashSet<Type> types;

public ConverterDisablingContractResolver(IEnumerable<Type> types)
{
if (types == null)
throw new ArgumentNullException();
this.types = new HashSet<Type>(types);
}

bool ContainsType(Type type)
{
return types.Contains(type);
}

protected override JsonConverter ResolveContractConverter(Type objectType)
{
// This could be enhanced to deal with inheritance. I.e. if TBase is in types and has a converter then
// its converter should not be used for TDerived -- but if TDerived has its own converter then it should still be
// used, so simply returning null for TDerived would be wrong.
if (types.Contains(objectType))
return null;
return base.ResolveContractConverter(objectType);
}
}


Then, define a static member somewhere as follows, for performance reasons described here:



static IContractResolver shapeResolver = new ConverterDisablingContractResolver(new { typeof(TheShape) });


And serialize as follows:



var settings = new JsonSerializerSettings
{
ContractResolver = shapeResolver,
};
var json = JsonConvert.SerializeObject(root, settings);


Demo fiddle showing both options here.



Along the same lines, is there a way to have multiple converters that can be selected at serialization time based on a given condition?



Obviously you could add different converters to JsonSerializerSettings.Converters depending on some runtime condition. But if you want to supersede statically applied converters with runtime converters, you would need to set up your types appropriately, e.g. by using OverridableJsonConverterDecorator from this answer to Why Json.net does not use customized IsoDateTimeConverter?.






share|improve this answer





















  • This is great. I used the ContactResolver approach since the first solution was not relevant for the reasons you said and it worked perfectly
    – isaac.hazan
    Nov 21 at 7:42











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53401189%2fc-sharp-jsonconvert-using-the-default-converter-instead-of-the-custom-converter%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









2














The order in which JsonConverters are selected is documented as follows:




The priority of which JsonConverter is used is member attribute, then class attribute, and finally any converters passed to the JsonSerializer.




Thus you cannot disable a JsonConverter applied via JsonConverterAttribute using JsonSerializerSettings.Converters. Instead, you have the following options.



Firstly, if your TheShape is being referred to directly by some type you control, you could grab NoConverter from this answer to Selectively use default JSON converter and apply it to the referring members using JsonConverterAttribute or JsonPropertyAttribute.ItemConverterType, e.g. as follows:



public class ShapeContainer
{
[JsonConverter(typeof(NoConverter))]
public TheShape Shape { get; set; }

[JsonProperty(ItemConverterType = typeof(NoConverter))]
public List<TheShape> Shapes { get; set; }
}


Now NoConverter will supersede TheShapeSerializer for the properties where it is applied, and cause Json.NET to fall back on default serialization.



Secondly, if you cannot add member attributes to types where TheShape is used, you could create a custom contract resolver that overrides DefaultContractResolver.ResolveContractConverter and returns null for TheShape. First define the following contract resolver:



public class ConverterDisablingContractResolver : DefaultContractResolver
{
readonly HashSet<Type> types;

public ConverterDisablingContractResolver(IEnumerable<Type> types)
{
if (types == null)
throw new ArgumentNullException();
this.types = new HashSet<Type>(types);
}

bool ContainsType(Type type)
{
return types.Contains(type);
}

protected override JsonConverter ResolveContractConverter(Type objectType)
{
// This could be enhanced to deal with inheritance. I.e. if TBase is in types and has a converter then
// its converter should not be used for TDerived -- but if TDerived has its own converter then it should still be
// used, so simply returning null for TDerived would be wrong.
if (types.Contains(objectType))
return null;
return base.ResolveContractConverter(objectType);
}
}


Then, define a static member somewhere as follows, for performance reasons described here:



static IContractResolver shapeResolver = new ConverterDisablingContractResolver(new { typeof(TheShape) });


And serialize as follows:



var settings = new JsonSerializerSettings
{
ContractResolver = shapeResolver,
};
var json = JsonConvert.SerializeObject(root, settings);


Demo fiddle showing both options here.



Along the same lines, is there a way to have multiple converters that can be selected at serialization time based on a given condition?



Obviously you could add different converters to JsonSerializerSettings.Converters depending on some runtime condition. But if you want to supersede statically applied converters with runtime converters, you would need to set up your types appropriately, e.g. by using OverridableJsonConverterDecorator from this answer to Why Json.net does not use customized IsoDateTimeConverter?.






share|improve this answer





















  • This is great. I used the ContactResolver approach since the first solution was not relevant for the reasons you said and it worked perfectly
    – isaac.hazan
    Nov 21 at 7:42
















2














The order in which JsonConverters are selected is documented as follows:




The priority of which JsonConverter is used is member attribute, then class attribute, and finally any converters passed to the JsonSerializer.




Thus you cannot disable a JsonConverter applied via JsonConverterAttribute using JsonSerializerSettings.Converters. Instead, you have the following options.



Firstly, if your TheShape is being referred to directly by some type you control, you could grab NoConverter from this answer to Selectively use default JSON converter and apply it to the referring members using JsonConverterAttribute or JsonPropertyAttribute.ItemConverterType, e.g. as follows:



public class ShapeContainer
{
[JsonConverter(typeof(NoConverter))]
public TheShape Shape { get; set; }

[JsonProperty(ItemConverterType = typeof(NoConverter))]
public List<TheShape> Shapes { get; set; }
}


Now NoConverter will supersede TheShapeSerializer for the properties where it is applied, and cause Json.NET to fall back on default serialization.



Secondly, if you cannot add member attributes to types where TheShape is used, you could create a custom contract resolver that overrides DefaultContractResolver.ResolveContractConverter and returns null for TheShape. First define the following contract resolver:



public class ConverterDisablingContractResolver : DefaultContractResolver
{
readonly HashSet<Type> types;

public ConverterDisablingContractResolver(IEnumerable<Type> types)
{
if (types == null)
throw new ArgumentNullException();
this.types = new HashSet<Type>(types);
}

bool ContainsType(Type type)
{
return types.Contains(type);
}

protected override JsonConverter ResolveContractConverter(Type objectType)
{
// This could be enhanced to deal with inheritance. I.e. if TBase is in types and has a converter then
// its converter should not be used for TDerived -- but if TDerived has its own converter then it should still be
// used, so simply returning null for TDerived would be wrong.
if (types.Contains(objectType))
return null;
return base.ResolveContractConverter(objectType);
}
}


Then, define a static member somewhere as follows, for performance reasons described here:



static IContractResolver shapeResolver = new ConverterDisablingContractResolver(new { typeof(TheShape) });


And serialize as follows:



var settings = new JsonSerializerSettings
{
ContractResolver = shapeResolver,
};
var json = JsonConvert.SerializeObject(root, settings);


Demo fiddle showing both options here.



Along the same lines, is there a way to have multiple converters that can be selected at serialization time based on a given condition?



Obviously you could add different converters to JsonSerializerSettings.Converters depending on some runtime condition. But if you want to supersede statically applied converters with runtime converters, you would need to set up your types appropriately, e.g. by using OverridableJsonConverterDecorator from this answer to Why Json.net does not use customized IsoDateTimeConverter?.






share|improve this answer





















  • This is great. I used the ContactResolver approach since the first solution was not relevant for the reasons you said and it worked perfectly
    – isaac.hazan
    Nov 21 at 7:42














2












2








2






The order in which JsonConverters are selected is documented as follows:




The priority of which JsonConverter is used is member attribute, then class attribute, and finally any converters passed to the JsonSerializer.




Thus you cannot disable a JsonConverter applied via JsonConverterAttribute using JsonSerializerSettings.Converters. Instead, you have the following options.



Firstly, if your TheShape is being referred to directly by some type you control, you could grab NoConverter from this answer to Selectively use default JSON converter and apply it to the referring members using JsonConverterAttribute or JsonPropertyAttribute.ItemConverterType, e.g. as follows:



public class ShapeContainer
{
[JsonConverter(typeof(NoConverter))]
public TheShape Shape { get; set; }

[JsonProperty(ItemConverterType = typeof(NoConverter))]
public List<TheShape> Shapes { get; set; }
}


Now NoConverter will supersede TheShapeSerializer for the properties where it is applied, and cause Json.NET to fall back on default serialization.



Secondly, if you cannot add member attributes to types where TheShape is used, you could create a custom contract resolver that overrides DefaultContractResolver.ResolveContractConverter and returns null for TheShape. First define the following contract resolver:



public class ConverterDisablingContractResolver : DefaultContractResolver
{
readonly HashSet<Type> types;

public ConverterDisablingContractResolver(IEnumerable<Type> types)
{
if (types == null)
throw new ArgumentNullException();
this.types = new HashSet<Type>(types);
}

bool ContainsType(Type type)
{
return types.Contains(type);
}

protected override JsonConverter ResolveContractConverter(Type objectType)
{
// This could be enhanced to deal with inheritance. I.e. if TBase is in types and has a converter then
// its converter should not be used for TDerived -- but if TDerived has its own converter then it should still be
// used, so simply returning null for TDerived would be wrong.
if (types.Contains(objectType))
return null;
return base.ResolveContractConverter(objectType);
}
}


Then, define a static member somewhere as follows, for performance reasons described here:



static IContractResolver shapeResolver = new ConverterDisablingContractResolver(new { typeof(TheShape) });


And serialize as follows:



var settings = new JsonSerializerSettings
{
ContractResolver = shapeResolver,
};
var json = JsonConvert.SerializeObject(root, settings);


Demo fiddle showing both options here.



Along the same lines, is there a way to have multiple converters that can be selected at serialization time based on a given condition?



Obviously you could add different converters to JsonSerializerSettings.Converters depending on some runtime condition. But if you want to supersede statically applied converters with runtime converters, you would need to set up your types appropriately, e.g. by using OverridableJsonConverterDecorator from this answer to Why Json.net does not use customized IsoDateTimeConverter?.






share|improve this answer












The order in which JsonConverters are selected is documented as follows:




The priority of which JsonConverter is used is member attribute, then class attribute, and finally any converters passed to the JsonSerializer.




Thus you cannot disable a JsonConverter applied via JsonConverterAttribute using JsonSerializerSettings.Converters. Instead, you have the following options.



Firstly, if your TheShape is being referred to directly by some type you control, you could grab NoConverter from this answer to Selectively use default JSON converter and apply it to the referring members using JsonConverterAttribute or JsonPropertyAttribute.ItemConverterType, e.g. as follows:



public class ShapeContainer
{
[JsonConverter(typeof(NoConverter))]
public TheShape Shape { get; set; }

[JsonProperty(ItemConverterType = typeof(NoConverter))]
public List<TheShape> Shapes { get; set; }
}


Now NoConverter will supersede TheShapeSerializer for the properties where it is applied, and cause Json.NET to fall back on default serialization.



Secondly, if you cannot add member attributes to types where TheShape is used, you could create a custom contract resolver that overrides DefaultContractResolver.ResolveContractConverter and returns null for TheShape. First define the following contract resolver:



public class ConverterDisablingContractResolver : DefaultContractResolver
{
readonly HashSet<Type> types;

public ConverterDisablingContractResolver(IEnumerable<Type> types)
{
if (types == null)
throw new ArgumentNullException();
this.types = new HashSet<Type>(types);
}

bool ContainsType(Type type)
{
return types.Contains(type);
}

protected override JsonConverter ResolveContractConverter(Type objectType)
{
// This could be enhanced to deal with inheritance. I.e. if TBase is in types and has a converter then
// its converter should not be used for TDerived -- but if TDerived has its own converter then it should still be
// used, so simply returning null for TDerived would be wrong.
if (types.Contains(objectType))
return null;
return base.ResolveContractConverter(objectType);
}
}


Then, define a static member somewhere as follows, for performance reasons described here:



static IContractResolver shapeResolver = new ConverterDisablingContractResolver(new { typeof(TheShape) });


And serialize as follows:



var settings = new JsonSerializerSettings
{
ContractResolver = shapeResolver,
};
var json = JsonConvert.SerializeObject(root, settings);


Demo fiddle showing both options here.



Along the same lines, is there a way to have multiple converters that can be selected at serialization time based on a given condition?



Obviously you could add different converters to JsonSerializerSettings.Converters depending on some runtime condition. But if you want to supersede statically applied converters with runtime converters, you would need to set up your types appropriately, e.g. by using OverridableJsonConverterDecorator from this answer to Why Json.net does not use customized IsoDateTimeConverter?.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 20 at 22:32









dbc

53.2k869121




53.2k869121












  • This is great. I used the ContactResolver approach since the first solution was not relevant for the reasons you said and it worked perfectly
    – isaac.hazan
    Nov 21 at 7:42


















  • This is great. I used the ContactResolver approach since the first solution was not relevant for the reasons you said and it worked perfectly
    – isaac.hazan
    Nov 21 at 7:42
















This is great. I used the ContactResolver approach since the first solution was not relevant for the reasons you said and it worked perfectly
– isaac.hazan
Nov 21 at 7:42




This is great. I used the ContactResolver approach since the first solution was not relevant for the reasons you said and it worked perfectly
– isaac.hazan
Nov 21 at 7:42


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53401189%2fc-sharp-jsonconvert-using-the-default-converter-instead-of-the-custom-converter%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

404 Error Contact Form 7 ajax form submitting

How to know if a Active Directory user can login interactively

TypeError: fit_transform() missing 1 required positional argument: 'X'