0

I'm working with an old legacy project with interesting entity property naming. My task is to replace Nancy modules with MVC API Controllers. What I want to achieve here is to serialize the JSON response from controllers where only the first character in DTO property names are affected.

Here is my issue:

Example:

public class FooDto
{
  public string INFooBar { get; set; }
}

This is serialized to:

{
  "inFooBar": null
}

aspnet core 3.1 is using CamelCaseNaming strategy by default and this is totally correct serialization to camel case but what I want to achieve is (the system has a lot of consumers, so the serialization must not be changed):

{
  "iNFooBar": null
}

The old Nancy endpoints are doing this somehow.

My work around is to override the DefaultNamingStrategy and explicitly lower case the first character in a Custom naming strategy:

public class CustomNamingStrategy : DefaultNamingStrategy
    {
        protected override string ResolvePropertyName(string name)
        {
            var pascalCasingName = base.ResolvePropertyName(name);
            var firstCharacterLower = pascalCasingName.Substring(0, 1). ToLowerInvariant();
            var result = $"{firstCharacterLower}{pascalCasingName.Remove(0, 1)}";
            return result;
        }
    }

Startup.cs:

services.AddMvc()
  .AddNewtonsoftJson(options =>
    {
      options.SerializerSettings.ContractResolver = new DefaultContractResolver
        {
          NamingStrategy = new CustomNamingStrategy()
        };
    });

My questions are:

  • Is there any built-in support for this behaviour, that I have missed?
  • Does anyone else have a more clever solution for this issue?
albin
  • 607
  • 6
  • 10
  • 2
    This is the correct way to solve this problem using Json.NET. Naming strategies were implemented in. Json.NET 9.0 precisely so we could specify our own rules for name transformation while serializing. – dbc May 10 '21 at 13:35
  • 1
    That being said, you should replace `ToLower()` with `ToLowerInvariant()`. Otherwise you'll get the wrong result for `I` in the Turkish culture, see [C#- ToLower() is sometimes removing dot from the letter “I”](https://stackoverflow.com/q/6600954/3744182) and [Why is this Turkish character being corrupted when I lowercase it?](https://stackoverflow.com/q/42887533/3744182). – dbc May 10 '21 at 13:39
  • 1
    You could probably eliminate some of the intermediate string allocations in your `ResolvePropertyName()`. But overall, using a naming strategy is already the "clever" way to specify your own casing rule, see [How to apply a general rule for remapping all property names when serializing with Json.NET?](https://stackoverflow.com/q/46476903/3744182). – dbc May 10 '21 at 13:50
  • @dbc Thanks for the `ToLowerInvariant` hint! – albin May 10 '21 at 14:20
  • You're welcome. So, how to resolve this question? Close as a duplicate of the questions mentioned above? – dbc May 10 '21 at 18:23
  • 1
    Yes, I think it's fair to categorize this question as duplicate to https://stackoverflow.com/q/46476903/3744182. I am however not able to close it as duplicate. Thank's again @dbc – albin May 14 '21 at 18:28

0 Answers0