2013-10-25 5 views
1

Наше приложение LOB - это клиентское серверное приложение, которое использует бизнес-объекты CSLA, эти бизнес-объекты сериализуются с использованием NetDataContractSerializer. Серверная сторона работает на WCF, а клиент имеет конечные точки..NET 4.5.1 Исключение сериализации WCF

Все это работает при запуске клиентского программного обеспечения из Windows 7 или Windows 8 с установленным .NET 4.5.

При запуске клиентского программного обеспечения в Windows 8 или Windows 8.1 с последней платформой .NET 4.5.1 возникает следующее исключение.

Форматировщик бросил исключение при попытке десериализации сообщения: Была ошибку при попытке десериализации параметра http://ws.lhotka.net/WcfDataPortal:FetchResult. Сообщение InnerException было «Ошибка в строке 1 позиция 11619.« Элемент » « m_serializationArray »из пространства имен « http://schemas.microsoft.com/2003/10/Serialization/Arrays »не ожидается. Ожидающий элемент 'm_keyRehashCount'. '. Пожалуйста, см. InnerException для получения более подробной информации.

Самое внутреннее исключение составляет

Ошибка в строке 1 позицию 11619. 'элемент' '' из m_serializationArray пространства имен 'http://schemas.microsoft.com/2003/10/Serialization/Arrays' не ожидается. Ожидающий элемент 'm_keyRehashCount'.

Я ничего не могу найти об этом в stackoverflow или в google, я разместил этот же вопрос на форумах CSLA и, возможно, также должен опубликовать его на Connect. Но, может быть, мне повезло?

мне нужно некоторое время, чтобы сделать копию моей среды разработки, прежде чем я обновить .NET Framework для 4.5.1

я могу думать о двух возможных решений:

  • обновить сервер 2008 для .NET 4.5 0,1.
  • заставить клиентское программное обеспечение использовать .NET 4,5

Можно ли заставить клиентское программное обеспечение для использования только с .NET 4.5? Любые другие идеи?

+0

Я из команды совместимости с Microsoft .net. Не могли бы вы отправить нам простой проект, который может воспроизвести эту проблему для netfx45compat на microsoft.com, чтобы исследовать эту проблему? – Praburaj

+0

Я сделаю все возможное, но в ближайшие пару дней я занят – rfcdejong

+0

Это происходит при использовании ConcurrentDictionary внутри модели, я пошлю модифицированный проект образца csla. – rfcdejong

ответ

3

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

NetDataContractSerializer более ограничительный, чем DataContractSerializer согласно документации.

NetDataContractSerializer отличается от DataContractSerializer в одном важном образом: NetDataContractSerializer включает в себя информацию о типе CLR в сериализованном XML, в то время как DataContractSerializer не делает. Поэтому NetDataContractSerializer может использоваться только в том случае, если оба сериализационных и десериализационных конца имеют одни и те же типы CLR.

Я считаю, что тип ConcurrentDictionary в 4.5.1 добавила свойство или переменную-член с именем m_keyRehashCount, которая не найдена в версии 4.5 ConcurrentDictionary. При попытке де-сериализовать этот объект на машине 4.5.1 - сериализатор ожидает, что это недостающее свойство приведет к этому исключению.

<m_keyRehashCount>0</m_keyRehashCount> 

Вот несколько способов решить эту проблему:

  1. Upgrade машину сервера, а также для 4.5.1. .net 4.5.1 - это бесплатное обновление до .net 4.5, которое также имеет исправления для некоторых проблем совместимости, обнаруженных в .net 4.5.

  2. Использование DataContractSerializer вместо NetDataContractSerializer как это не ожидает, что точно такое же CLR типов в оба сериализации и десериализация заканчивается.

  3. Изменить вместо словаря вместо of ConcurrentDictionary как я вижу, этот тип работает fine.
1

Если вы ранее сериализовали объекты (с сериализацией с пред 4.5.1), которые содержат ConcurrentDictionary, вы можете десериализовать его в 4.5.1, используя следующий пример.

Этот пример помогает десериализовать уже сериализованные объекты ConcurrentDictionary, создавая новый класс, который может десериализоваться с использованием XML-кода сериализации ConcurrentDictionary, см. Также другие ответы.

using System; 
using System.Collections; 
using System.Collections.Concurrent; 
using System.Collections.Generic; 
using System.Linq; 
using System.Runtime.Serialization; 
using System.Text; 
using ClassLibrary1.Model; 

namespace SerializaerDesrializer 
{ 
    [DataContract] 
    public class CompositeDictionaryHolder 
    { 
     // Old serialized data member: 
     //[DataMember] 
     //private MyConcurrentDictionary<int, string> _concuurentDictionary = new MyConcurrentDictionary<int, string>(); 

     private ConcurrentDictionary<int, string> _concuurentDictionaryInternal = new ConcurrentDictionary<int, string>(); 

     [DataMember] 
     private InternalArray _concuurentDictionary; 

     public CompositeDictionaryHolder() 
     { 
      // Just an example: 
      _concuurentDictionaryInternal.TryAdd(1, "1"); 
      _concuurentDictionaryInternal.TryAdd(2, "2"); 
      _concuurentDictionaryInternal.TryAdd(3, "3"); 
     } 


     /// <summary> 
     /// Get the data array to be serialized 
     /// </summary> 
     [OnSerializing] 
     private void OnSerializing(StreamingContext context) 
     { 
      // save the data into the serialization array to be saved 
      _concuurentDictionary = new InternalArray(_concuurentDictionaryInternal.ToArray()); 
     } 

     /// <summary> 
     /// Construct the dictionary from a previously seiralized one 
     /// </summary> 
     [OnDeserialized] 
     private void OnDeserialized(StreamingContext context) 
     { 
      _concuurentDictionaryInternal = new ConcurrentDictionary<int, string>(_concuurentDictionary.m_serializationArray); 
     } 
    } 

    [DataContract(
     Namespace = "http://schemas.microsoft.com/2003/10/Serialization/Arrays")] 
    public class InternalArray 
    { 
     public InternalArray() 
     { 

     } 
     public InternalArray(KeyValuePair<int, string>[] serializationArray) 
     { 
      m_serializationArrayInternal = serializationArray; 
     } 

     [DataMember] 
     public KeyValuePair<int, string>[] m_serializationArray 
     { 
      get { return m_serializationArrayInternal; } 
      set { m_serializationArrayInternal = value; } 
     } 

     private KeyValuePair<int, string>[] m_serializationArrayInternal; 
    } 
} 
+0

Спасибо за ваш ответ, если когда-нибудь мы столкнемся с симулятивной проблемой, я всегда могу это понять. В любом случае, Прабурадж уже ответил на мой вопрос. – rfcdejong

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