2013-02-15 2 views
3

У меня есть структура IntEx - словом, она расширяет нормальный Int32 и обрабатывается. Это выглядит следующим образом:Сериализация WCF JSON на объекте с IXmlSerializable

[Serializable] 
public struct IntEx 
{ 
    private int internalValue; 

    private IntEx(int value) 
    { 
     internalValue = value; 
    } 

    public static implicit operator int(IntEx value) 
    { 
     return value.internalValue; 
    } 

    public static implicit operator IntEx(int value) 
    { 
     return new IntEx(value); 
    } 
} 

Если мы посылаем эту структуру через WCF он сериализации с помощью JSON и вывод будет «хорошо выглядеть». Как мы будем использовать пример кода ниже:

DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(TestClass)); 

using (MemoryStream stream = new MemoryStream()) 
{ 
    jsonSerializer.WriteObject(stream, testClass); 

    string serializedString = Encoding.UTF8.GetString(stream.GetBuffer()); 

    Console.WriteLine("JSON: {0}", serializedString); 
} 
public class TestClass 
{ 
    public int I1 { get; set; } 

    public IntEx I2 { get; set; } 
} 

Output выглядеть следующим образом

JSON: {"I1":11,"I2":{"internalValue":22}} 

Клиента и других "третьей частей" использование Progam этот формат (с internalValue).

Использование IntEx широко используется в моем приложении. Один из объектов сериализуется в XML (некоторая настройка). Этот объект использует IntEx как тип. Так что я должен реализовать IXmlSerializable структурировать Intex, потому что без этого свойства сериализовать как пустой узел

XML: <TestClass><I1>11</I1><I2 /></TestClass> 

Если изменить Intex использовать IXmlSerializable

[Serializable] 
public struct IntEx : IXmlSerializable 
{ 
    private int internalValue; 

    private IntEx(int value) 
    { 
     internalValue = value; 
    } 

    public static implicit operator int(IntEx value) 
    { 
     return value.internalValue; 
    } 

    public static implicit operator IntEx(int value) 
    { 
     return new IntEx(value); 
    } 

    System.Xml.Schema.XmlSchema IXmlSerializable.GetSchema() 
    { 
     return null; 
    } 

    void IXmlSerializable.ReadXml(System.Xml.XmlReader reader) 
    { 
     throw new NotImplementedException(); 
    } 

    void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer) 
    { 
     writer.WriteValue(internalValue); 
    } 
} 

выход XML выглядит хорошо

XML: <TestClass><I1>11</I1><I2>22</I2></TestClass> 

но все мои услуги ломаются, так как сейчас JSON выглядит так:

JSON: {"I1":11,"I2":"<IntEx xmlns=\"http:\/\/schemas.datacontract.org\/2004\/07\/TestJSONSerialization\">22<\/IntEx>"} 

Я читал, что если вы используете IXmlSerializable, сериализация JSON «думаю», что я отвечаю за сериализацию, оставьте этот объект для меня ... Но как я могу вернуться к «оригинальной» сериализации.

Так что теперь я в тупике ... Мне нужно JSON выход выглядеть раньше, но я также необходимо, как некоторые силы, чтобы писать настройки в XML с двумя условиями:

  1. internalValue должен оставаться частным - он не должен быть доступен с использованием какой-либо публичной собственности
  2. Я не хочу переписывать кучу кода chaneg (использовать бокс для свойств JSON) или изменять все возможные свойства или класс, которые можно сохранить в файле XML.

Так может кто-нибудь дать мне ключ, как я могу решить эту проблему? :/

+0

Вы нашли решение для этого? Как безопасно смешивать DataContractJsonSerializer с IXmlSerializable? –

+0

К сожалению, я этого не сделал.Я использовал некоторое дерьмовое обходное решение, чтобы заставить код работать в то время. Полагая, что когда-нибудь кто-то ответит на мой вопрос (или я найду решение) и исправлю этот беспорядок. – Carnifex

+0

Тогда на данный момент я поеду с двумя одинаковыми классами (один для Json, один для Xml) и конвертер из одного класса в другой. –

ответ

0

Вы можете использовать DataContractJsonSerializer с IDataContractSurrogate. используя IDataContractSurrogate для преобразования «IntEx» в «IntExJson», а «IntExJson» не нужно наследовать от IXmlSerializable.

IDataContractSurrogate может использоваться для удаления некоторых объектов из объекта и преобразования в аналогичный объект. а затем использовать:

public DataContractJsonSerializer(Type type, IEnumerable<Type> knownTypes, int maxItemsInObjectGraph, bool ignoreExtensionDataObject, IDataContractSurrogate dataContractSurrogate, bool alwaysEmitTypeInformation); 

для сериализации объекта в json. десериализация такая же.

Смежные вопросы