Pregunta

En un contexto de servicio web, tengo la siguiente clase que hereda de la clase Mammal. La clase Mammal se define en un proxy. No puedo cambiar la definición de esa clase. Como necesito agregar algunos métodos a la clase Mammal en el lado del cliente, heredé Mammal y creé Giraffe.

namespace TestApplication
{  
    public class Giraffe : Mammal
    {
        public Giraffe()
        {
        }
    }
}

Cuando llamo a un WebMethod que espera un objeto de tipo Mammal, aparece la siguiente excepción que me dice que no se espera Giraffe.

  Error: System.InvalidOperationException: There was an error generating the XML document. ---> System.InvalidOperationException: The type Giraffe was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically.
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterPaymentRequestAuthorization.Write6_Tender(String n, String ns, Tender o, Boolean isNullable, Boolean needType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterPaymentRequestAuthorization.Write12_PaymentRequestAuthorization(String n, String ns, PaymentRequestAuthorization o, Boolean isNullable, Boolean needType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterPaymentRequestAuthorization.Write13_PaymentRequestAuthorization(Object o)
   --- End of inner exception stack trace ---

¿Hay alguna solución alternativa? Realmente no puedo agregar XmlInclude ...

¿Fue útil?

Solución

Para agregar métodos, debe usar clases parciales. Intente agregar un archivo de segunda clase con (en el espacio de nombres correcto, etc.):

partial class Mammal {
    public void ExtraMethod() {...}
}

La palabra clave partial le dice al compilador que permita que la clase se divida en varios archivos, ideal para escenarios de generación de código. Sin embargo, exige la palabra clave partial en cada archivo; los miembros simplemente se combinan (excepto los métodos parciales en C # 3.0 que tienen su propio comportamiento sutil). ¡ espero que wsdl.exe (o lo que sea) incluya esto!

Otros consejos

Si solo desea agregar métodos a una clase que no puede cambiar, simplemente cree métodos de extensión.

public static class MammalExt {
public static void ExtraMethod(this Mammal mammal) {...}}

Aunque si mamífero es una clase generada por proxy, debería ser una clase parcial.

Tienes que usar XmlInclude. Es tu única opción. Tienes que decirle al serializador qué clase estarás serializando, ya que tiene que generar el código para hacer la serialización.

Se me ocurrió al escribir esto, que podría salirse con la suya si Giraffe implementa IXmlSerializable, pero eso es aún más trabajo.

La respuesta correcta es usar una clase parcial. Cuando abre el proyecto del cliente y genera una referencia web, Visual Studio analiza el WSDL y genera una clase llamada Mammal para usted. Esta clase solo es visible para el proyecto del cliente, por lo que no tiene que preocuparse por el lado del servidor.

Digamos que tiene una referencia web llamada MyWebService. Luego habrá una clase llamada MyWebService.Mammal . Para agregar miembros a esta clase, todo lo que necesita hacer es crear un nuevo archivo fuente que contenga esto:

namespace MyWebService {
    public partial class Mammal {
        public void ExtraMethod() { ... }
    }
}

Cuando llama a un método en su servicio web que devuelve un Mamífero , el código de referencia web creará una nueva instancia de su " mejorado " Clase de mamífero y copie los valores del xml en el cable a la instancia.

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