Pregunta

En una pregunta anterior sobre serializar un objeto en un XmlDocument en C # , necesitaba serializar cierta información de falla en un XmlDocument que fue devuelto por una llamada de servicio web de estilo asmx. En el cliente necesito eliminar la serialización del XmlDocument de nuevo a un objeto.

Esto es bastante sencillo si conoce el tipo, pero me di cuenta de que quería un enfoque flexible en el que el tipo de deserialización también esté codificado en el XmlDocument . Actualmente lo estoy haciendo manualmente agregando un XmlNode al XmlDocument que tiene el nombre del tipo, calculado de la siguiente manera:

    Type type = fault.GetType();
    string assemblyName = type.Assembly.FullName;

    // Strip off the version and culture info
    assemblyName = assemblyName.Substring(0, assemblyName.IndexOf(",")).Trim();

    string typeName = type.FullName + ", " + assemblyName;

Luego, en el cliente, primero obtengo este nombre de tipo del XmlDocument , y creo el objeto de tipo que se pasa al XmlSerialiser de esta manera:

        object fault;
        XmlNode faultNode = e.Detail.FirstChild;
        XmlNode faultTypeNode = faultNode.NextSibling;

        // The typename of the fault type is the inner xml of the first node
        string typeName = faultTypeNode.InnerXml;
        Type faultType = Type.GetType(typeName);

        // The serialised data for the fault is the second node
        using (var stream = new StringReader(faultNode.OuterXml))
        {
            var serialiser = new XmlSerializer(faultType);
            objectThatWasSerialised = serialiser.Deserialize(stream);
        }

        return (CastToType)fault;

Entonces, este es un enfoque de fuerza bruta, y me preguntaba si hay una solución más elegante que de alguna manera incluya el nombre de tipo del tipo serializado automáticamente, en lugar de grabarlo manualmente en otro lugar.

¿Fue útil?

Solución

Me enfrenté a un problema similar y se me ocurrió la misma solución. En lo que a mí respecta, esa es la única forma de mantener los tipos junto con los valores en la serialización XML.

Veo que estás cortando la versión de ensamblaje como yo también. Pero me gustaría mencionar que tendrá problemas con los tipos genéricos, ya que su firma se ve así:

System.Nullable`1[[System.Int, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

Así que hice una función para cortar solo las versiones de ensamblaje, lo que parece ser suficiente para deshacerse de los problemas de versiones:

    private static string CutOutVersionNumbers(string fullTypeName)
    {
        string shortTypeName = fullTypeName;
        var versionIndex = shortTypeName.IndexOf("Version");
        while (versionIndex != -1)
        {
            int commaIndex = shortTypeName.IndexOf(",", versionIndex);
            shortTypeName = shortTypeName.Remove(versionIndex, commaIndex - versionIndex + 1);
            versionIndex = shortTypeName.IndexOf("Version");
        }
        return shortTypeName;
    }

Otros consejos

Neil, ¿por qué necesitas que sea del tipo mismo tanto en el cliente como en el servidor?

¿Sigue utilizando ASMX en el cliente? Esa sería una razón, ya que ASMX no admite fallas correctamente.

Además, ¿tiene tantos tipos de fallas diferentes que una simple instrucción switch no puede determinar el tipo correcto de usar?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top