Расширение CamelCasePropertyNamesContractResolver не работает - PullRequest
0 голосов
/ 17 октября 2018

Я расширяю Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver и применяю новый преобразователь в моем WebApi:

public static void Register(HttpConfiguration config)
{
    var json = config.Formatters.JsonFormatter.SerializerSettings;
    json.ContractResolver = new CustomPropertyNamesContractResolver();
    json.Formatting = Formatting.Indented;

    config.MapHttpAttributeRoutes();
}

, и вот переопределенный метод моего пользовательского преобразователя имен (CustomPropertyNamesContractResolver class):

protected override string ResolvePropertyName(string propertyName)
{
    if (propertyName.Equals("ID"))
        return "id";

    // return the camelCase
    propertyName = base.ResolvePropertyName(propertyName);

    if (propertyName.EndsWith("ID"))
        propertyName = propertyName.Substring(0, propertyName.Length - 1) + "d";
    return propertyName;
}

Моя проблема в том, что результаты действительно в случае верблюда, но свойства, такие как "QuestionID", никогда не преобразуются в "questionId" - то, что я продолжаю получать, это "questionID".

Плюс,Мой пользовательский метод ResolvePropertyName () никогда не вызывается (проверял его с точками останова), поэтому кажется, что только метод ResolvePropertyName () моего родительского класса (CamelCasePropertyNamesContractResolver) вызывается каким-то образом.

Теперь, когда я наследую напрямую отDefaultContractResolver (который является родителем CamelCasePropertyNamesContractResolver) вызывается мой пользовательский метод ResolvePropertyName ().

Может кто-нибудь объяснить мне, что здесь происходит?Я что-то упустил?

1 Ответ

0 голосов
/ 17 октября 2018

ResolvePropertyName() больше не вызывается CamelCasePropertyNamesContractResolver.Это задокументировано в Выпуск № 950: критическое изменение в 9.0.1 для пользовательских средств разрешения контрактов? , которое было разрешено JamesNK следующим образом:

JamesNK прокомментировал 4 июля 2016 года

Да, теперь это сломается.Этот метод [ResolvePropertyName] никогда не вызывается из-за изменений в том, как работает CamelCasePropertyNamesContractResolver.

Что вы можете сделать, это унаследовать от CamelCaseNamingStrategy и сделать что-то подобное, а затем назначить это DefaultContractResolver.Обратите внимание, что вам следует кэшировать распознаватель контракта в статической переменной, чтобы он не создавался постоянно.

Следуя приведенным там советам, вы должны наследовать от CamelCaseNamingStrategy примерно так:

public class CustomNamingStrategy : CamelCaseNamingStrategy
{
    protected override string ResolvePropertyName(string propertyName)
    {
        if (propertyName.Equals("ID"))
            return "id";

        // return the camelCase
        propertyName = base.ResolvePropertyName(propertyName);

        if (propertyName.EndsWith("ID"))
            propertyName = propertyName.Substring(0, propertyName.Length - 1) + "d";
        return propertyName;
    }
}

Затем установите его на DefaultContractResolver.NamingStrategy примерно так:

json.ContractResolver = new DefaultContractResolver { NamingStrategy = new CustomNamingStrategy() };

Или, поскольку я считаю, что ASP.NET Web API использует свой собственный обработчик контрактовJsonContractResolver, вы можете изменить NamingStrategy существующего config.Formatters.JsonFormatter.SerializerSettings.ContractResolver, предполагая, что преобразователь уже выделен в настройках:

var resolver = json.ContractResolver as DefaultContractResolver ?? new DefaultContractResolver();
resolver.NamingStrategy = new CustomNamingStrategy();
json.ContractResolver  = resolver;

(Примечание - у меня нетсам не тестировал с использованием уже существующего резольвера.)

...