Универсальная утилита C # для проверки строки JSON на анонимный тип - PullRequest
0 голосов
/ 15 февраля 2019

У меня есть строка JSON.Я хочу проверить, содержит ли он анонимный объект.Если это так, верните значение.Если это не так, вернуть значение по умолчанию.Затем я хочу иметь возможность повторить это несколько раз для разных анонимных объектов.

Вот пример кода, который я сейчас реализовал, но, очевидно, он дублируется каждый раз и не очень «чистый».

var displayDataBy = 0;
var displayDataByDefinition = new { DisplayDataBy = new { Key = "string", Value = displayDataBy } };
var displayDataByResult = JsonConvert.DeserializeAnonymousType(this.OhdContentPageParameters, displayDataByDefinition);
try { displayDataBy = displayDataByResult.DisplayDataBy.Value; }
catch { }

var xMinsOeeToShow = 480;
var xMinsOeeToShowDefinition = new { XMinsOeeToShow = new { Key = "string", Value = xMinsOeeToShow } };
var xMinsOeeToShowResult = JsonConvert.DeserializeAnonymousType(this.OhdContentPageParameters, xMinsOeeToShowDefinition);
try { xMinsOeeToShow = xMinsOeeToShowResult.XMinsOeeToShow.Value; }
catch { }

Я бы предпочел, чтобы это был универсальный метод, который я мог вызывать для каждого анонимного типа.Также было бы неплохо не полагаться на try / catch.Можно ли это сделать?

ОБНОВЛЕНИЕ ...

Это прекрасно работает для int, bool и double:

public static T2 DeserializeValue<T, T2>(this string json, T definition, T2 defaultValue, Func<T, T2?> getValueFunc) where T2 : struct
{
    var jsonAnon = JsonConvert.DeserializeAnonymousType(json, definition);
    return getValueFunc(jsonAnon) ?? defaultValue;
}

Я добавил этодля струн:

public static string DeserializeStringValue<T>(this string json, T definition, string defaultValue, Func<T, string> getValueFunc)
{
    var jsonAnon = JsonConvert.DeserializeAnonymousType(json, definition);
    return getValueFunc(jsonAnon) ?? defaultValue;
}

Ответы [ 4 ]

0 голосов
/ 15 февраля 2019

Используя вспомогательный класс для обобщения выполняемых вами операций,

public static class DeserializeHelpers {
    public static T2 DeserializeValue<T,T2>(this string s, T def, T2 defans, Func<T, T2?> getAnsFn) where T2 : struct {
        var jsonAnon = JsonConvert.DeserializeAnonymousType(s, def);
        return getAnsFn(jsonAnon) ?? defans;
    }

    public static T2 DeserializeClass<T,T2>(this string s, T def, T2 defans, Func<T, T2> getAnsFn) where T2 : class {
        var jsonAnon = JsonConvert.DeserializeAnonymousType(s, def);
        return getAnsFn(jsonAnon) ?? defans;
    }
}

Вы можете немного упростить свой код следующим образом.Я оставил некоторые подробные кодировки, так как вы, похоже, шли на все, чтобы не указывать явный тип для Value, но я был вынужден предположить, что это был тип значения, позволяющий null возвращать из метода доступа к элементулямбда.Если класс может быть возвращен, вам нужно будет использовать помощник класса.

var displayDataBy = 0;
var displayDataByDefinition = new { DisplayDataBy = new { Key = "string", Value = displayDataBy } };
var displayDataByResult = this.OhdContentPageParameters.DeserializeValue(displayDataByDefinition, displayDataBy, x => x.DisplayDataBy?.Value);

var xMinsOeeToShow = 480;
var xMinsOeeToShowDefinition = new { XMinsOeeToShow = new { Key = "string", Value = xMinsOeeToShow } };
var xMinsOeeToShowResult = this.OhdContentPageParameters.DeserializeValue(xMinsOeeToShowDefinition, xMinsOeeToShow, x => x.XMinsOeeToShow?.Value);

Я использовал метод расширения для Deserialize..., но, конечно, это мог быть обычный метод.

Если вам не нужно повторно использовать определение анонимного типа, вы можете передать это встроенное значение методу Deserialize....

0 голосов
/ 15 февраля 2019

Надеюсь, это поможет.

public object GetStuffDone(int displayDataBy, string KeyName, string Ohd, int defaultValue)
        {
            var definition = new { theData = new { Key = KeyName, Value = displayDataBy } };

            var result = JsonConvert.DeserializeAnonymousType(Ohd, definition);


            return result != null ? result.theData.Value : defaultValue;
        }
0 голосов
/ 15 февраля 2019

Почему бы не использовать JObject.Parse вместо десериализации?

Func<Type, string, object, string, object> getValue = (T, path, dflt, json) =>
            {
                var jobj = JObject.Parse(json);
                return jobj.SelectToken(path).ToObject(T) ?? dflt;
            };

var result = (int)getValue(typeof(int), "*.Value", 0, this.OhdContentPageParameters);

С этим вы можете пройти Json через JsonPath и установить значение по умолчанию.Нет необходимости объявлять анонимные типы.

Есть ли необходимость явно знать свойство JSON, из которого вы извлекаете?

0 голосов
/ 15 февраля 2019

попробуйте с условными операторами: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-conditional-operators

var displayDataBy = 0;
…..
displayDataBy = (displayDataByResult?.DisplayDataBy?.Value == null ? displayDataBy : displayDataByResult.DisplayDataBy.Value);


var xMinsOeeToShow = 480;
…...
xMinsOeeToShow = (xMinsOeeToShowResult?.XMinsOeeToShow?.Value == null ? xMinsOeeToShow : xMinsOeeToShowResult.XMinsOeeToShow.Value);
...