Как игнорировать свойства при сериализации в json, которые не содержат атрибутов - PullRequest
2 голосов
/ 28 июля 2011

Я использую Entity Framework для генерации своих моделей.Я хочу сообщить некоторые из этих моделей через JSON.Проблема в том, что я не хочу, чтобы материал, который EF привязывает к модели, был сериализован (EntityKey, EntityState и все свойства EntityCollection <>)

Поскольку EF генерирует эти модели, декорируя свойства с помощью ScriptIgnore иличто-то подобное на самом деле неосуществимо.

Есть ли способ с любым сериализатором json сериализовать объект и заставить его игнорировать поля, которые не требуют от меня изменения источника для моих моделей?(Однако я могу добавить к моделям, если это поможет, поскольку они объявлены как частичные классы)

Ответы [ 3 ]

1 голос
/ 20 октября 2011

Я только что столкнулся с подобной проблемой, в данном случае это свойство пользовательского объекта в модели Linq to SQL, которое я бы предпочел просто сериализовать в базу данных и из нее, а не настраивать множество дополнительных поля и дополнительные конструкторы. Я не уверен, насколько это соответствует вашей ситуации, но это должно быть адаптировано.

В большинстве решений, которые я видел, требовалось включить либо атрибуты (что невозможно из-за автоматической генерации кода), либо преобразование пользовательских преобразователей (излишнее, особенно если вы хотите захватить вложенные объекты и т. Д.).

Я думаю, что все свойства, которые мне не нужны, уже имеют атрибуты из-за LinqToSql, поэтому вместо того, чтобы вручную получать свойства, которые я хочу, затем пытаться их сериализовать, сначала Serialize, а затем DeSerialize. Это дает вам ваш объектный граф, с которым намного проще работать, и все ваши вложения были сделаны для вас.

Затем получите имена членов, которые нам не нужны. Как вы получите это, зависит только от вас, может даже случиться дать ему имена вручную так же, как вы исключили бы из привязки модели в MVC. В моем случае немного Linq и немного размышлений дает нам имена всех свойств, которые генерирует Linq to SQL.

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

Наконец, снова сериализуйте ваш словарь.

public string JsonMinusProperties(object toSerialize)
    {
        //Replace this with your preferred way of getting your unwanted properties
        var LinqMemberNames = toSerialize.GetType().GetProperties().Where(y=>
            y.GetCustomAttributes(true).Any(x =>
                x.GetType().Namespace == "System.Data.Linq.Mapping"
            )
        ).Select(x=>x.Name);

        JavaScriptSerializer js = new JavaScriptSerializer();
        string json = js.Serialize(toSerialize);
        var tempobj = js.DeserializeObject(json) as Dictionary<string, object>;
        foreach (string linqMember in LinqMemberNames)
        {
            tempobj.Remove(linqMember);
        }
        return js.Serialize(tempobj);
    }

Это удалит только с первого уровня, хотя в принципе должно быть легко пройти словарь, если требуется удалить более глубокие свойства.

0 голосов
/ 29 июля 2011

В JayRock вы можете создать свой собственный IExporter. Основная форма может выглядеть так:

class FooExporter : IExporter
{
    public void Export(ExportContext context, object value, JsonWriter writer)
    {
        var properties = value.GetType().GetProperties();

        writer.WriteStartObject();

        foreach (var property in properties)
        {
            var propertyValue = property.GetValue(value, null);
            if (!JsonNull.LogicallyEquals(propertyValue))
            {
                writer.WriteMember(property.Name);
                context.Export(propertyValue, writer);
            }
        }

        writer.WriteEndObject();
    }

    public Type InputType
    {
        get { return typeof(Foo); }
    }
}

Вы можете изменить это любым способом (например, игнорировать все свойства, имеющие определенное имя; используйте конкретный тип в конструкторе) Затем вы можете использовать его так:

var context = JsonConvert.CurrentExportContextFactory();
context.Register(new FooExporter());
// always use this context
JsonConvert.CurrentExportContextFactory = () => context;
string json = JsonConvert.ExportToString(new Foo { … });

Другой вариант - реализовать IJsonExportable в ваших сущностях. У него есть метод Export(), очень похожий на описанный выше.

0 голосов
/ 28 июля 2011

Если вы используете DataContractJsonSerializer для сериализации в JSON, то он будет сериализовать только свойства, имеющие атрибут [ DataMember ].

Другой вариант, который следует рассмотреть, - это отдельный объект DTO для данных, которые вы хотите представить в JSON. Этот объект будет построен из ваших моделей сущностей. Преимущества этого подхода состоят в том, что у вас есть явный класс DTO, который определяет контракт данных и не связан с базовой моделью сущностей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...