una significado serialize serializar que objeto leer deserialize deserializar crear como cadena and c# .net wcf serialization generic-list

significado - serializar y deserializar json c#



WCF: Serialización y deserialización de colecciones genéricas (4)

Obtuve este error mientras transportaba una lectura IList desde una base de datos a través de LINQ. El WCF se alojó en IIS 7 en un Windows Server 2008 x64.

El grupo de aplicaciones se colgó sin advertencias.

[ServiceBehavior] public class Webservice : IWebservice { public IList<object> GetObjects() { return Database.Instance.GetObjects(); } }

No es exactamente el mismo problema pero puede tener la misma causa.

La resolución para instalar MS es la revisión KB973110 http://support.microsoft.com/kb/971030/en-us

Tengo un equipo de clase que tiene una lista genérica:

[DataContract(Name = "TeamDTO", IsReference = true)] public class Team { [DataMember] private IList<Person> members = new List<Person>(); public Team() { Init(); } private void Init() { members = new List<Person>(); } [System.Runtime.Serialization.OnDeserializing] protected void OnDeserializing(StreamingContext ctx) { Log("OnDeserializing of Team called"); Init(); if (members != null) Log(members.ToString()); } [System.Runtime.Serialization.OnSerializing] private void OnSerializing(StreamingContext ctx) { Log("OnSerializing of Team called"); if (members != null) Log(members.ToString()); } [System.Runtime.Serialization.OnDeserialized] protected void OnDeserialized(StreamingContext ctx) { Log("OnDeserialized of Team called"); if (members != null) Log(members.ToString()); } [System.Runtime.Serialization.OnSerialized] private void OnSerialized(StreamingContext ctx) { Log("OnSerialized of Team called"); Log(members.ToString()); }

Cuando uso esta clase en un servicio WCF, obtengo la siguiente salida de registro

OnSerializing of Team called System.Collections.Generic.List 1[XXX.Person] OnSerialized of Team called System.Collections.Generic.List 1[XXX.Person] OnDeserializing of Team called System.Collections.Generic.List 1[XXX.Person] OnDeserialized of Team called XXX.Person[]

Después de que los members deserialización sean una matriz y ya no sean una lista genérica, aunque el tipo de campo es IList <> (?!) Cuando trato de enviar este objeto de regreso a través del servicio WCF obtengo el resultado de registro

OnSerializing of Team called XXX.Person[]

Después de esto, mi prueba de unidad se bloquea con System.ExecutionEngineException, lo que significa que el servicio WCF no puede serializar la matriz. (tal vez porque esperaba un IList <>)

Entonces, mi pregunta es: ¿Alguien sabe por qué el tipo de mi IList <> es una matriz después de deserializar y por qué no puedo serializar mi objeto Team por más tiempo después de eso?

Gracias


Parece que su referencia de servicio WCF está creando una clase de proxy en lugar de usar el tipo existente. Las clases proxy solo pueden usar matrices simples y ningún tipo específico de .NET como la Lista genérica.

Para evitar esta conversión de clase de proxy, en la pantalla Agregar referencia de servicio, haga clic en el botón Avanzado y luego asegúrese de que esté marcado "Reutilizar tipos en los ensamblados a los que se hace referencia". Esto asegurará que la clase existente (con la Lista genérica) se utilice al serializar y deserializar el objeto.


Te has encontrado con uno de los errores de DataContractSerializer .

Solución: cambie su declaración de miembro privado a:

[DataMember] private List<Person> members = new List<Person>();

O cambie la propiedad a:

[DataMember()] public IList<Person> Feedback { get { return m_Feedback; } set { if ((value != null)) { m_Feedback = new List<Person>(value); } else { m_Feedback = new List<Person>(); } } }

Y funcionará. El error de Microsoft Connect está here

Este problema ocurre cuando deserializa un objeto con un IList<T> DataMember y luego trata de serializar la misma instancia nuevamente.

Si quieres ver algo genial:

using System; using System.Collections.Generic; class TestArrayAncestry { static void Main(string[] args) { int[] values = new[] { 1, 2, 3 }; Console.WriteLine("int[] is IList<int>: {0}", values is IList<int>); } }

Se imprimirá int[] is IList<int>: True .

Sospecho que esta es posiblemente la razón por la que lo ves como una matriz después de la deserialización, pero no es muy intuitivo.

Sin embargo, si llamas al método Add () en IList<int> de la matriz, arroja NotSupportedException .

Una de esas peculiaridades de .NET.


Tomado directamente de mi blog. Espero que sea util:

Recientemente me encontré con un problema en el que estábamos consumiendo un servicio WCF y utilizando un encuadernador de modelo personalizado en nuestra aplicación ASP.NET MVC. Todo funcionó bien cuando estábamos serializando nuestros ILists. IList se serializa en matrices de forma predeterminada. Terminé convirtiendo nuestras matrices en ILists utilizando Reflection y llamando al siguiente método en el cuaderno de modelo personalizado. Así es como se ve el método:

public object ConvertArraysToIList(object returnObj) { if (returnObj != null) { var allProps = returnObj.GetType().GetProperties().Where(p => p.PropertyType.IsPublic && p.PropertyType.IsGenericType && p.PropertyType.Name==typeof(IList<>).Name).ToList(); foreach (var prop in allProps) { var value = prop.GetValue(returnObj,null); //set the current property to a new instance of the IList<> var arr=(System.Array)value; Type listType=null; if(arr!=null) { listType= arr.GetType().GetElementType(); } //create an empty list of the specific type var listInstance = typeof(List<>) .MakeGenericType(listType) .GetConstructor(Type.EmptyTypes) .Invoke(null); foreach (var currentValue in arr) { listInstance.GetType().GetMethod("Add").Invoke(listInstance, new[] { currentValue }); } prop.SetValue(returnObj, listInstance, null); } } return returnObj; }