5

In the new System.Text.Json; namespace is there something like IContractResolver i am trying to migrate my project away from Newtonsoft.

This is one of the classes i am trying to move:

public class SelectiveSerializer : DefaultContractResolver
{
private readonly string[] fields;

public SelectiveSerializer(string fields)
{
  var fieldColl = fields.Split(',');
  this.fields = fieldColl
      .Select(f => f.ToLower().Trim())
      .ToArray();
}

protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
  var property = base.CreateProperty(member, memberSerialization);
  property.ShouldSerialize = o => fields.Contains(member.Name.ToLower());

  return property;
}
}
Askolein
  • 2,992
  • 2
  • 26
  • 36
Dživo Jelić
  • 1,604
  • 2
  • 22
  • 47
  • Did you use .net core 3.0?Could you share why do you want to migrate from `Newtonsoft` to `System.Text.Json`?Actually,net core 3.0 could support `Newtonsoft`.And how did your code work?Is is used to lower case the body data? – Rena Nov 20 '19 at 06:39
  • @Rena This code was used for building our own select function for api. example: select=FirstName,Email,Id serializer would only serialize specified fields. Similar to how odata does it since we are moving away from odata – Dživo Jelić Nov 20 '19 at 06:56
  • The equivalent types in `System.Text.Json` -- [`JsonClassInfo`](https://github.com/dotnet/corefx/blob/master/src/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs) and [`JsonPropertyInfo`](https://github.com/dotnet/corefx/blob/master/src/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfo.cs) -- are **internal**. There is an open enhancement [Equivalent of DefaultContractResolver in System.Text.Json #42001](https://github.com/dotnet/corefx/issues/42001) asking for a public equivalent. – dbc Nov 25 '19 at 19:11
  • @dbc good to know :) – Dživo Jelić Nov 27 '19 at 16:27

1 Answers1

2

The equivalent types in System.Text.Json -- JsonClassInfo and JsonPropertyInfo -- are internal. There is an open enhancement Equivalent of DefaultContractResolver in System.Text.Json #31257 asking for a public equivalent. – dbc Nov 25 at 19:11

Github issues:

Please try this:
I wrote this as an extension to System.Text.Json to offer missing features: https://github.com/dahomey-technologies/Dahomey.Json.

You will find support for programmatic object mapping.

Define your own implementation of IObjectMappingConvention:

public class SelectiveSerializer : IObjectMappingConvention
{
    private readonly IObjectMappingConvention defaultObjectMappingConvention = new DefaultObjectMappingConvention();
    private readonly string[] fields;

    public SelectiveSerializer(string fields)
    {
        var fieldColl = fields.Split(',');
        this.fields = fieldColl
            .Select(f => f.ToLower().Trim())
            .ToArray();
    }

    public void Apply<T>(JsonSerializerOptions options, ObjectMapping<T> objectMapping) where T : class
    {
        defaultObjectMappingConvention.Apply<T>(options, objectMapping);
        foreach (IMemberMapping memberMapping in objectMapping.MemberMappings)
        {
            if (memberMapping is MemberMapping<T> member)
            {
                member.SetShouldSerializeMethod(o => fields.Contains(member.MemberName.ToLower()));
            }
        }
    }
}

Define your class:

public class Employee
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
}

Setup json extensions by calling on JsonSerializerOptions the extension method SetupExtensions defined in the namespace Dahomey.Json:

JsonSerializerOptions options = new JsonSerializerOptions();
options.SetupExtensions();

Register the new object mapping convention for the class:

options.GetObjectMappingConventionRegistry().RegisterConvention(
    typeof(Employee), new SelectiveSerializer("FirstName,Email,Id"));

Then serialize your class with the regular Sytem.Text.Json API:

Employee employee = new Employee
{
    Id = 12,
    FirstName = "John",
    LastName = "Doe",
    Email = "john.doe@acme.com"
};
        
string json = JsonSerializer.Serialize(employee, options);
// {"Id":12,"FirstName":"John","Email":"john.doe@acme.com"};
dbc
  • 91,441
  • 18
  • 186
  • 284