C # Изменить JsonReader при переопределении StringEnumConverter [duplicate]

Я могу получить ваш запрошенный формат в одной строке без использования библиотек и методов Date, просто regex:

var d = (new Date()).toString().replace(/\S+\s(\S+)\s(\d+)\s(\d+)\s.*/,'$2-$1-$3');
// date will be formatted as "14-Oct-2015" (pass any date object in place of 'new Date()')

Update: Как указывал @RobG, вывод Date.prototype.toString ( ) зависит от реализации. Поэтому используйте это с осторожностью и при необходимости измените, если вы используете это решение. В моем тестировании это надежно работает в Северной Америке, где основные браузеры (Chrome, Safari, Firefox и IE) возвращают одинаковый строковый формат.

3
задан dbc 17 August 2015 в 18:21
поделиться

1 ответ

Тип перечисления является аргументом objectType для ReadJson . Однако несколько моментов:

  1. Вам нужно обрабатывать типы с нулевым перечислением.
  2. Вам нужно обрабатывать перечисления [Flag] . Json.NET записывает их как списки значений, разделенных запятыми.
  3. Вам нужно обработать случай перечисления с недопустимым значением. Json.NET записывает их как числовые значения, когда StringEnumConverter.AllowIntegerValues == true и выбрасывает исключение иначе.

Вот подкласс StringEnumConverter , который обрабатывает эти случаи, вызывая базовый класс, добавив или удалив префикс типа, когда это необходимо:

public class TypePrefixEnumConverter : StringEnumConverter
{
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        bool isNullable = (Nullable.GetUnderlyingType(objectType) != null);
        Type enumType = (Nullable.GetUnderlyingType(objectType) ?? objectType);
        if (!enumType.IsEnum)
            throw new JsonSerializationException(string.Format("type {0} is not a enum type", enumType.FullName));
        var prefix = enumType.Name + "_";

        if (reader.TokenType == JsonToken.Null)
        {
            if (!isNullable)
                throw new JsonSerializationException();
            return null;
        }

        // Strip the prefix from the enum components (if any).
        var token = JToken.Load(reader);
        if (token.Type == JTokenType.String)
        {
            token = (JValue)string.Join(", ", token.ToString().Split(',').Select(s => s.Trim()).Select(s => s.StartsWith(prefix) ? s.Substring(prefix.Length) : s).ToArray());
        }

        using (var subReader = token.CreateReader())
        {
            while (subReader.TokenType == JsonToken.None)
                subReader.Read();
            return base.ReadJson(subReader, objectType, existingValue, serializer); // Use base class to convert
        }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var array = new JArray();
        using (var tempWriter = array.CreateWriter())
            base.WriteJson(tempWriter, value, serializer);
        var token = array.Single();

        if (token.Type == JTokenType.String && value != null)
        {
            var enumType = value.GetType();
            var prefix = enumType.Name + "_";
            token = (JValue)string.Join(", ", token.ToString().Split(',').Select(s => s.Trim()).Select(s => (!char.IsNumber(s[0]) && s[0] != '-') ? prefix + s : s).ToArray());
        }

        token.WriteTo(writer);
    }
}

Затем вы можете использовать его везде, где вы могли бы использовать StringEnumConverter , например:

        var settings = new JsonSerializerSettings { Converters = new JsonConverter[] { new TypePrefixEnumConverter() } };
        var json = JsonConvert.SerializeObject(myClass, Formatting.Indented, settings);
7
ответ дан dbc 29 August 2018 в 02:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: