0

I receive an exception when deserializing RecurrenceInfo in a big project:

Newtonsoft.Json.JsonSerializationException: Cannot populate list type DevExpress.XtraScheduler.CustomFieldCollection at Newtonsoft.Json.... <<< omitted 20 Newtonsoft internal calls

The problem is reproducable with this MCVE:

RecurrenceInfo test = (RecurrenceInfo)RecurrenceBuilder.Weekly(DateTime.MinValue, DateTime.MaxValue).ByDay(WeekDays.Monday | WeekDays.Tuesday | WeekDays.Wednesday | WeekDays.Thursday | WeekDays.Friday).Build();
var copy = JsonConvert.DeserializeObject<RecurrenceInfo>(JsonConvert.SerializeObject(test));

I've noticed that in json there is this empty CustomFields:

"Recurrence": {
    ...
    "OccurrenceCount": 1,
    "CustomFields": [],
    "Id": "ef7ff4c3-9a3f-4cea-ab08-aa5f63e58c8c",
    ...

If I remove it from json, then there is no exception.

Because the project is big, it's a hassle to change something. So I am looking for a way to do it with minimum effort and affect on the rest.

Question

Given:

public class A
{
    [JsonProperty]
    public RecurrenceInfo B { get; set; }        
}

How to exclude property B.CustomFields from being serialized (or deserialized)? Ideally via some attribute(pseudocode):

[JsonProperty]
[CustomResolver(typeof(MyCustomResolver))]
public RecurrenceInfo B { get; set; }        

I suspect the answer is "no, you have to specify custom resolver as deserializer settings" (I am trying to avoid that), but maybe someone sees something I don't or can think of a nice trick or a totally different solution?

Sinatr
  • 20,892
  • 15
  • 90
  • 319
  • Is the problem that you cannot modify `B` at all, and you also cannot easily modify your project settings? – dbc Jul 20 '21 at 14:15
  • @dbc, I can't modify `RecurrenceInfo` type. Not sure what you mean with `B` or project settings. I can modify `A`, adding more properties. Currently my workaround is to serialize/deserialize `B` value as xml using another `string` property (which works flawlessly). – Sinatr Jul 20 '21 at 14:27
  • 1
    Then, assuming you have some custom contract resolver type `MyCustomResolver`, you could apply `[JsonConverter(typeof(AlternateContractResolverConverter), typeof(MyCustomResolver))]` to `public RecurrenceInfo B { get; set; }` where `AlternateContractResolverConverter` comes from [this answer](https://stackoverflow.com/a/40599731/3744182) to [JSON .NET Custom Name Resolver for Sub-Properties](https://stackoverflow.com/q/40597532/3744182). – dbc Jul 21 '21 at 02:47
  • Does that answer your question? – dbc Jul 21 '21 at 14:45
  • @dbc, maybe. I am not able to test it right now. I am currently more happy with my solution (another property) and keeping the question opened for devexpress experts, maybe they will add something. Otherwise I would just delete/close question. – Sinatr Jul 21 '21 at 14:52

1 Answers1

0

You can simply prevent a property of being serialized using the [JsonIgnore] attribute, but take care which library you are using. System.Test.Json.Serialization or Newtonsoft.Json because the attribute is called the same on both and will not throw an error, just not work if your cross the libraries.

Mr.Deer
  • 476
  • 6
  • 17
  • Where should I put this attribute to prevent `B.CustomFields` from being serialized? – Sinatr Jul 20 '21 at 08:37
  • You should put it over the B custom fields declaration. Just on top of the propery you want to ignore. – Mr.Deer Jul 20 '21 at 08:38
  • `RecurrenceInfo` is a type defined in library, I can't put attributes there. – Sinatr Jul 20 '21 at 08:39
  • Maybe could you inherit the object like C : RecurrenceInfo and hide the variable with an ignore attribute on top ? – Mr.Deer Jul 20 '21 at 08:44
  • Inheriting? Hmm.. not sure. Perhaps I should try [adding attribute at run-time](https://stackoverflow.com/q/14663763/1997232). – Sinatr Jul 20 '21 at 08:47