Arhn - архитектура программирования

Использование атрибута Serializable в модели в WebAPI

У меня есть следующий сценарий: я использую WebAPI и возвращаю результаты JSON потребителю на основе модели. Теперь у меня есть дополнительное требование сериализовать модели в base64, чтобы иметь возможность сохранять их в кеше и/или использовать их для целей аудита. Проблема в том, что когда я добавляю атрибут [Serializable] к модели, чтобы преобразовать модель в Base64, вывод JSON изменяется следующим образом:

Модель:

[Serializable]
public class ResortModel
{
    public int ResortKey { get; set; }

    public string ResortName { get; set; }
}

Без атрибута [Serializable] вывод JSON будет следующим:

{
    "ResortKey": 1,
    "ResortName": "Resort A"
}

С атрибутом [Serializable] вывод JSON:

{
    "<ResortKey>k__BackingField": 1,
    "<ResortName>k__BackingField": "Resort A"
}

Как я могу использовать атрибут [Serializable] без изменения вывода JSON?


Ответы:


1

По умолчанию Json.NET игнорирует атрибут Serializable. Однако, согласно комментарию к этот ответ от Maggie Ying (цитируется ниже, потому что комментарии не должны длиться долго), WebAPI переопределяет это поведение, что приводит к вашему выводу.

Сериализатор Json.NET по умолчанию устанавливает для IgnoreSerializableAttribute значение true. В WebAPI мы устанавливаем для него значение false. Причина, по которой вы столкнулись с этой проблемой, заключается в том, что Json.NET игнорирует свойства: «Теперь Json.NET обнаруживает типы, которые имеют атрибут SerializableAttribute, и сериализует все поля этого типа, как общедоступные, так и частные, и игнорирует свойства» (цитата из Джеймс .newtonking.com/archive/2012/04/11/…)

Простой пример, демонстрирующий такое же поведение без WebAPI, может выглядеть так:

using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
namespace Scratch
{
    [Serializable]
    class Foo
    {
        public string Bar { get; set; }
    }

    class Program
    {
        static void Main()
        {
            var foo = new Foo() { Bar = "Blah" };
            Console.WriteLine(JsonConvert.SerializeObject(foo, new JsonSerializerSettings()
                {
                    ContractResolver = new DefaultContractResolver()
                    {
                        IgnoreSerializableAttribute = false
                    }
                }));
        }
    }
}

Есть несколько способов обойти это поведение. Один из них — украсить вашу модель простым атрибутом JsonObject:

[Serializable]
[JsonObject]
class Foo
{
    public string Bar { get; set; }
}

Другой способ — переопределить настройки по умолчанию в файле Application_Start(). Согласно этот ответ, настройки по умолчанию должны делать это:

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings = new Newtonsoft.Json.JsonSerializerSettings();

Если это не сработает, вы можете явно указать это:

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings()
    {
        ContractResolver = new DefaultContractResolver()
        {
            IgnoreSerializableAttribute = true
        }
    };
30.04.2015
  • Спасибо, Барт, отличный ответ! Я решил использовать GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings = new Newtonsoft.Json.JsonSerializerSettings();, чтобы не украшать каждую модель [JsonObject]. 30.04.2015
  • Ты спас мне жизнь, друг! Большое спасибо! 14.08.2020
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..