Подтвердить что ты не робот

Сериализация нескольких свойств DateTime в одном классе с использованием разных форматов для каждого из них

У меня есть класс с двумя свойствами DateTime. Мне нужно сериализовать каждое из свойств с другим форматом. Как мне это сделать? Я пробовал:

JsonConvert.SerializeObject(obj, Formatting.None,
      new IsoDateTimeConverter {DateTimeFormat = "MM.dd.yyyy"});

Это решение не работает для меня, потому что оно применяет формат даты ко всем свойствам. Есть ли способ сериализации каждого свойства DateTime в другом формате? Может быть, есть какой-то атрибут?

4b9b3361

Ответ 1

NewtonSoft.Json имеет структуру, которую трудно понять, вы можете использовать что-то вроде следующего настраиваемого конвертера, чтобы делать то, что вы хотите:

[TestMethod]
public void Conversion()
{
    var obj = new DualDate()
    {
        DateOne = new DateTime(2013, 07, 25),
        DateTwo = new DateTime(2013, 07, 25)
    };
    Assert.AreEqual("{\"DateOne\":\"07.25.2013\",\"DateTwo\":\"2013-07-25T00:00:00\"}", 
        JsonConvert.SerializeObject(obj, Formatting.None, new DualDateJsonConverter()));
}

class DualDate
{
    public DateTime DateOne { get; set; }
    public DateTime DateTwo { get; set; }
}

class DualDateJsonConverter : JsonConverter
{

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

        JObject result = new JObject();

        DualDate dd = (DualDate)value;

        result.Add("DateOne", JToken.FromObject(dd.DateOne.ToString("MM.dd.yyyy")));
        result.Add("DateTwo", JToken.FromObject(dd.DateTwo));
        result.WriteTo(writer);
    }

    // Other JsonConverterMethods
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(DualDate);
    }

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

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

Ответ 2

Простым способом справиться с этой ситуацией является подкласс IsoDateTimeConverter для создания настраиваемого конвертера дат для каждого формата даты, который вам нужен. Например:

class MonthDayYearDateConverter : IsoDateTimeConverter
{
    public MonthDayYearDateConverter()
    {
        DateTimeFormat = "MM.dd.yyyy";
    }
}

class LongDateConverter : IsoDateTimeConverter
{
    public LongDateConverter()
    {
        DateTimeFormat = "MMMM dd, yyyy";
    }
}

Затем вы можете использовать атрибут [JsonConverter] для украшения отдельных свойств DateTime в любых классах, которые нуждаются в специальном форматировании:

class Foo
{
    [JsonConverter(typeof(MonthDayYearDateConverter))]
    public DateTime Date1 { get; set; }

    [JsonConverter(typeof(LongDateConverter))]
    public DateTime Date2 { get; set; }

    // Use default formatting
    public DateTime Date3 { get; set; }
}

Демо:

Foo foo = new Foo
{
    Date1 = DateTime.Now,
    Date2 = DateTime.Now,
    Date3 = DateTime.Now
};

string json = JsonConvert.SerializeObject(foo, Formatting.Indented);
Console.WriteLine(json);

Вывод:

{
  "Date1": "03.03.2014",
  "Date2": "March 03, 2014",
  "Date3": "2014-03-03T10:25:49.8885852-06:00"
}

Ответ 3

Вы можете создать пользовательский класс даты, который наследует IsoDateTimeConverter и передает формат конструктору. В атрибутах вы можете указать, какой формат соответствует каждому свойству. См. Следующий код:

public class LoginResponse
{
    [JsonProperty("access_token")]
    public string AccessToken { get; set; }
    [JsonProperty("token_type")]
    public string TokenType { get; set; }
    [JsonProperty("expires_in")]
    public DateTime ExpiresIn { get; set; }
    [JsonProperty("userName")]
    public string Username { get; set; }
    [JsonConverter(typeof(CustomDateFormat), "EEE, dd MMM yyyy HH:mm:ss zzz")]
    [JsonProperty(".issued")]
    public DateTime Issued { get; set; }
    [JsonConverter(typeof(CustomDateFormat), "MMMM dd, yyyy")]
    [JsonProperty(".expires")]
    public DateTime Expires { get; set; }
}

public class CustomDateFormat : IsoDateTimeConverter
{
    public CustomDateFormat(string format)
    {
        DateTimeFormat = format;
    }
}

Ответ 4

Я понимаю, что это старый вопрос, но я наткнулся на него во время поиска того же вопроса.

У Newtonsoft теперь есть свойство DateFormatString в классе JsonSerializerSettings, который вы можете использовать. Я пришел к этому вопросу, ища ответ и только что нашел свойство, я использовал его, как показано ниже, и он работает следующим образом:

    private const string _StrDateFormat = "yyyy-MM-dd HH:mm:ss";

    private static string GetJSON(object value)
    {

        return JsonConvert.SerializeObject(value, new JsonSerializerSettings
        {
            DateFormatString = _StrDateFormat
        });
    }

Когда value будет иметь объект DateTime, он преобразует его в строку, соответствующую строке _StrDateFormat.

Возможно, эта официальная ссылка может быть обновлена?

С уважением.