C#, MVC 3 и задание формата сериализации в json

Для того чтобы отдать json-ответ в ASP.NET MVC используется метод Json(), который есть у стандартного класса Controller. Этот метод скрывает внутри себя создания объекта класса JsonResult, который в свою очередь в методе ExecuteResult использует JavaScriptSerializer для сериализации переданного ему объекта.

Использование его достаточно просто и интуитивно, до тех пор пока вы не столкнетесь с первыми трудностями – ими могут стать желание отобразить элементы enum'а в виде строки, а не цифровых значений (например "EnumItem" вместо порядкового номера элемента в енаме), или необходимость передать дату в формате ISO 8601, вместо того странного формата, который возвращает ASP.NET по-умолчанию (например "2014-01-14T18:00:00Z" вместо "/Date(1389722400000)/"). И тут, к сожалению, настает время выкидывать стандартные средства и начинать использовать сторонние библиотеки.

Наверняка вы уже работали с Json.NET, а если нет, то самое время начать это делать.

Чтобы использовать её вместо стандартной сериализации достаточно создать класс JsonNetResult и везде заменить вызовы типа return Json(model), на создание объекта return new JsonNetResult(model).

Собственно, вот сам класс:

public class JsonNetResult : ActionResult
{
    public JsonNetResult()
    {
        SerializerSettings = new JsonSerializerSettings
        {
            Converters = new List<JsonConverter>()
        };
    }

    public JsonNetResult(object data)
        : this()
    {
        Data = data;
    }

    public JsonNetResult(object data, params JsonConverter[] converters)
        : this()
    {
        Data = data;
        foreach (var jsonConverter in converters)
        {
            SerializerSettings.Converters.Add(jsonConverter);
        }
    }

    public Encoding ContentEncoding { get; set; }
    public string ContentType { get; set; }
    public object Data { get; set; }
    public JsonSerializerSettings Settings { get; set; }

    public JsonSerializerSettings SerializerSettings { get; set; }
    public Formatting Formatting { get; set; }

    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
            throw new ArgumentNullException("context");

        HttpResponseBase response = context.HttpContext.Response;

        response.ContentType = !string.IsNullOrEmpty(ContentType)
            ? ContentType
            : "application/json";

        if (ContentEncoding != null)
            response.ContentEncoding = ContentEncoding;

        if (Data != null)
        {
            var writer = new JsonTextWriter(response.Output) {Formatting = Formatting};

            JsonSerializer serializer = JsonSerializer.Create(SerializerSettings);
            serializer.Serialize(writer, Data);

            writer.Flush();
        }
    }
}

А вот примеры гибкой настройки конвертирования в json

Указываем свой формат даты:

return new JsonNetResult(data,new IsoDateTimeConverter{DateTimeFormat = "yyyy MM dd"});

Указываем с помощью атрибута, что значение enam'а надо сериализовать в виде строки (можно было бы передать конвертор так же, как в предыдущем примере)

[JsonConverter(typeof(StringEnumConverter))]
public UserType AccountType { get; set; }

Передаем настройки сериализации и включаем игнорирование полей со значением null

return new JsonNetResult(data,
    new JsonSerializerSettings
    {
        NullValueHandling = NullValueHandling.Ignore,
        Converters = new List<JsonConverter> {new IsoDateTimeConverter()}
    });

Это простейшие и самые распространенные примеры использования библиотеки Json.NET в качестве сериализатора, возможности библиотеки гораздо шире и желающие могут ознакомиться с ними в документации


comments powered by HyperComments
Яндекс.Метрика