Pergunta

Em uma pergunta anterior sobre serializadas um objeto a um XmlDocument em C # , eu precisava publicando algumas informações culpa a um XmlDocument que foi retornado de uma chamada webservice de estilo asmx. No cliente eu preciso para de-serialise o XmlDocument de volta para um objeto.

Este é o suficiente simples se você sabe o tipo, mas eu percebi que queria uma abordagem flexível em que o tipo de de-serialise também está codificado no XmlDocument. Atualmente estou fazendo isso manualmente, adicionando um XmlNode ao XmlDocument que tem o nome do tipo, calculado da seguinte forma:

    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;

Em seguida, no cliente I primeiro obter este nome tipo de volta da XmlDocument, e criar o tipo de objeto que é passado para o XmlSerialiser assim:

        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;

Portanto, esta é uma abordagem de força bruta, e eu queria saber se há uma solução mais elegante que de alguma forma inclui o typename do tipo serializado automaticamente, em vez de gravá-la manualmente em outro lugar?

Foi útil?

Solução

Eu havia enfrentado um problema semelhante e eu vim com a mesma solução. Tanto quanto eu estou em causa, que é a única maneira de manter os tipos em conjunto com os valores em serialização XML.

Eu vejo que você está cortando versão conjunto para fora como eu fiz também. Mas eu gostaria de mencionar, que você vai ter problemas com tipos genéricos como aparência de assinatura DELE assim:

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

Então eu fiz uma função apenas para cortar a versão do assembly (s), o que parece ser suficiente para se livrar de versionamento problemas:

    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;
    }

Outras dicas

Neil, por que você precisa que ele seja o mesma tipo no cliente e no servidor?

Você ainda está usando ASMX no cliente? Isso seria uma razão, como ASMX não suporta adequadamente falhas.

Além disso, você tem tantos tipos de falhas diferentes que um simples interruptor declaração não é possível determinar o tipo correto de usar?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top