Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Offer a way to override the way documents are serialized in json #311

Open
juchom opened this issue Aug 25, 2022 · 4 comments
Open

Offer a way to override the way documents are serialized in json #311

juchom opened this issue Aug 25, 2022 · 4 comments
Labels
enhancement New feature or request

Comments

@juchom
Copy link
Contributor

juchom commented Aug 25, 2022

Description
Currently when we send a document we use the internal JsonSerializerOptions JsonSerializerOptionsWriteNulls with this definition

internal static readonly JsonSerializerOptions JsonSerializerOptionsWriteNulls = new JsonSerializerOptions
{
    DefaultIgnoreCondition = JsonIgnoreCondition.Never,
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
};

I actually don't like the default behaviour of this settings, it converts enum as int, I prefer to convert them as string.

Some people may not like the CamelCase and want some other settings.

Basic example

We should add an api call like SetGlobalJsonSerializerOptions or a ctor that accept one and make sure that the DefaultIgnoreCondition = JsonIgnoreCondition.Never other it will throws.

This test is very important because ignoring null values may lead to data losss for your customers.

If I'm correct in Constant.cs we have two JsonSerializerOptions :

JsonSerializerOptionsRemoveNulls this one is not supposed to be overridden, it is used for settings and match the api requirements.

JsonSerializerOptionsWriteNulls this one is only for documents and we may want to override the way we send documents to Meilisearch with the mandatory DefaultIgnoreCondition = JsonIgnoreCondition.Never.

What do you think of this ?

@alallema
Copy link
Contributor

Hi @juchom,
Thank you for your suggestions always very accurate. I find this idea very interesting and it would be great to implement. Obviously, I am not an expert on Dotnet so I trust you completely 😊 on this 🚀

@alallema alallema added the enhancement New feature or request label Aug 25, 2022
@juchom
Copy link
Contributor Author

juchom commented Aug 31, 2022

Actually, this is an interesting issue, in case other clients needs to do the same here are some side effects.

For exemple, let say we want to serialize our documents with PascalCase instead of camelCase and have our enum serialized as string.

We will use the following objects :

public class MovieWithEnum
{
    public int Id { get; set; }

    public string Name { get; set; }

    public MovieGenre Genre { get; set; }
}

public enum MovieGenre
{
    Action,
    Cartoon
}

Adding two movies will send this payload to Meilisearch :

var task = await index.AddDocumentsAsync(new[]
{
    new MovieWithEnum() { Id = 299537, Name = "Shazam!", Genre = MovieGenre.Action },
    new MovieWithEnum() { Id = 166428, Name = "How to Train Your Dragon: The Hidden World", Genre = MovieGenre.Cartoon },
});
[
   {
      "Id":299537,
      "Name":"Shazam!",
      "Genre":"Action"
   },
   {
      "Id":166428,
      "Name":"How to Train Your Dragon: The Hidden World",
      "Genre":"Cartoon"
   }
]

This is perfect, we have PascalCase properties and our Genre as string.

Now if we try to get our documents :

var docs = await index.GetDocumentsAsync<MovieWithEnum>();

We will have this payload :

{
   "results":[
      {
         "Id":299537,
         "Name":"Shazam!",
         "Genre":"Action"
      },
      {
         "Id":166428,
         "Name":"How to Train Your Dragon: The Hidden World",
         "Genre":"Cartoon"
      }
   ],
   "offset":0,
   "limit":20,
   "total":2
}

We have Meilisearch fields : results, offset, limit, total in camelCase
And our object fields : Id, Name, Genre in PascalCase and with Genre enum serialized as string.

Our problem is that System.Text.Json will throw an exception because it is case sensitive because and it expects all fields to be PascalCase.

In order to have this working I'm going to decorate Meilisearch's objects with JsonPropertyName to force the serializer to respect the response of the server whatever the options we use for our documents.

bors bot added a commit that referenced this issue Sep 5, 2022
314: Make Meilisearch's objects readonly and make sure json mapping works … r=alallema a=juchom

…regardless of JsonSerializerOptions

# Pull Request

## What does this PR do?
This PR makes sure that the server's response are well mapped to Meilisearch's objects.
Make this objects read only where it makes sense.

This is a first step for #311 



Co-authored-by: Julien Chomarat <[email protected]>
Co-authored-by: Amélie <[email protected]>
@xamir82
Copy link

xamir82 commented Dec 1, 2023

This is pretty essential actually. I'm surprised to find out it's not already supported. Especially, now that JSON serialization/deserialization source generators are becoming more and more prevalent, this is an increasingly pressing issue.
@ahmednfwela Sorry for pinging you, do you have any time to implement this by any chance? That would be greatly appreciated.

@mayrmax
Copy link

mayrmax commented Feb 5, 2024

As far as i see the only thing that needs to be adapted is to make the class public to allow overwriting?
Or am i missing something?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants