Добавить произвольный список полей при сериализации моих объектов [duplicate]

Вариант 1:

Предположим, что ваш timestring имеет формат, который выглядит так:

'2016-03-10 16:00:00.0'

В этом случае вы можете сделать простое регулярное выражение, чтобы преобразовать его в ISO 8601:

'2016-03-10 16:00:00.0'.replace(/ /g,'T')

Это выдаст следующий вывод:

'2016-03-10T16:00:00.0'

Это стандартный формат даты и времени, поддерживаемый всеми браузерами:

document.body.innerHTML = new Date('2016-03-10T16:00:00.0') // THIS IS SAFE TO USE

Вариант 2:

Предположим, что ваш timestring имеет формат, который выглядит следующим образом:

'02-24-2015 09:22:21 PM'

Здесь, вы можете сделать следующее regex:

'02-24-2015 09:22:21 PM'.replace(/-/g,'/');

Это также создает формат, поддерживаемый всеми браузерами:

document.body.innerHTML = new Date('02/24/2015 09:22:21 PM') // THIS IS SAFE TO USE

Вариант 3:

Предположим, что у вас есть строка времени, которую нелегко настроить в соответствии с одним из хорошо поддерживаемых стандартов.

В этом случае лучше всего просто разделите свою временную строку на разные части и используйте их как отдельные параметры для Date:

document.body.innerHTML = new Date(2016, 2, 26, 3, 24, 0); // THIS IS SAFE TO USE

28
задан Brian Rogers 24 September 2015 в 15:05
поделиться

3 ответа

Если вы используете Json.Net 5.0.5 или позже, и вы готовы изменить тип своего словаря от Dictionary<string, string> до Dictionary<string, object>, тогда один простой способ выполнить вы хотите добавить атрибут [JsonExtensionData] к свойству словаря следующим образом:

public class Test
{
    public string X { get; set; }

    [JsonExtensionData]
    public Dictionary<string, object> Y { get; set; }
}

Затем ключи и значения помеченного словаря будут сериализованы как часть родительского объекта. Бонус в том, что он работает и при десериализации: любые свойства в JSON, которые не соответствуют членам класса, будут помещены в словарь.

37
ответ дан Brian Rogers 25 August 2018 в 22:14
поделиться

Внедрить класс JsonConverter : класс CustomCreationConverter должен использоваться как базовый класс для создания пользовательского объекта.

Черновик версии конвертера (обработка ошибок может быть улучшена по вашему желанию):

internal class TestObjectConverter : CustomCreationConverter<Test>
{
    #region Overrides of CustomCreationConverter<Test>

    public override Test Create(Type objectType)
    {
        return new Test
            {
                Y = new Dictionary<string, string>()
            };
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        writer.WriteStartObject();

        // Write properties.
        var propertyInfos = value.GetType().GetProperties();
        foreach (var propertyInfo in propertyInfos)
        {
            // Skip the Y property.
            if (propertyInfo.Name == "Y")
                continue;

            writer.WritePropertyName(propertyInfo.Name);
            var propertyValue = propertyInfo.GetValue(value);
            serializer.Serialize(writer, propertyValue);
        }

        // Write dictionary key-value pairs.
        var test = (Test)value;
        foreach (var kvp in test.Y)
        {
            writer.WritePropertyName(kvp.Key);
            serializer.Serialize(writer, kvp.Value);
        }
        writer.WriteEndObject();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jsonObject = JObject.Load(reader);
        var jsonProperties = jsonObject.Properties().ToList();
        var outputObject = Create(objectType);

        // Property name => property info dictionary (for fast lookup).
        var propertyNames = objectType.GetProperties().ToDictionary(pi => pi.Name, pi => pi);
        foreach (var jsonProperty in jsonProperties)
        {
            // If such property exists - use it.
            PropertyInfo targetProperty;
            if (propertyNames.TryGetValue(jsonProperty.Name, out targetProperty))
            {
                var propertyValue = jsonProperty.Value.ToObject(targetProperty.PropertyType);
                targetProperty.SetValue(outputObject, propertyValue, null);
            }
            else
            {
                // Otherwise - use the dictionary.
                outputObject.Y.Add(jsonProperty.Name, jsonProperty.Value.ToObject<string>());
            }
        }

        return outputObject;
    }

    public override bool CanWrite
    {
        get { return true; }
    }

    #endregion
}

Код клиента:

var test = new Test
    {
        X = "123",
        Y = new Dictionary<string, string>
            {
                { "key1", "value1" },
                { "key2", "value2" },
                { "key3", "value3" },
            }
    };

string json = JsonConvert.SerializeObject(test, Formatting.Indented, new TestObjectConverter());
var deserializedObject = JsonConvert.DeserializeObject<Test>(json);

Обратите внимание: существует потенциальное столкновение имен свойств и имен ключей словарь.

8
ответ дан Sergey Brunov 25 August 2018 в 22:14
поделиться

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

public class DictionaryToJsonObjectConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return typeof(IDictionary<string, string>).IsAssignableFrom(objectType);
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            writer.WriteRawValue(JsonConvert.SerializeObject(value, Formatting.Indented));
        }
    }

Затем используйте его в своем классе poco.

public class Poco
{
        [JsonProperty("myid")]
        public string Id{ get; set; }

        [JsonProperty("properties")]
        [JsonConverter(typeof(DictionaryToJsonObjectConverter))]
        public IDictionary<string, string> Properties { get; set; }
    }
2
ответ дан Stephane 25 August 2018 в 22:14
поделиться
Другие вопросы по тегам:

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