2010-06-11 18 views
5

En nuestro entorno de producción, nuestros servicios WCF se serializan con XMLSerializer. Para hacerlo, nuestras interfaces de servicio tienen el atributo [XMLSerializerFormat]. Ahora, tenemos que cambiar a DataContractSerializer pero debemos ser compatibles con nuestros clientes existentes. Por lo tanto, tenemos que exponer cada servicio con ambos serializadores.¿Cómo admitir DataContractSerializer y XMLSerializer para el mismo contrato en el mismo host?

Tenemos una restricción: no queremos volver a definir cada interfaz contrato de dos veces, tenemos interfaces de contrato 50 servicios y no quieren tener

IIncidentServiceXml 
IIncidentServiceDCS 
IEmployeeServiceXml 
IEmployeeServiceDCS 
IContractServiceXml 
IContractServiceDCS 

¿Cómo podemos hacer eso?


Más información

Ésta es una descripción de lo que hemos tratado hasta ahora, pero estoy dispuesto a probar enfoques completamente diferentes:

Tratamos de crear todos los puntos finales por código en nuestra propia clase ServiceHostFactory. Básicamente creamos cada punto final dos veces. El problema es que en el tiempo de ejecución, WCF se queja de que el servicio tiene dos puntos finales con el mismo nombre de contacto pero con diferentes instancias de ContractDescription. El mensaje dice que debemos usar diferentes nombres de contrato o reutilizar la misma instancia de ContractDescription.

Otro intento:

También trató de hacerlo mediante el uso de diferentes espacios de nombres para cada instancia ContractDescription. De esa manera mantendríamos la misma interfaz de contrato (IIncidentService) pero con dos espacios de nombres diferentes:

http://ourcompany/XML/IIncidentService 
http://ourcompany/DCS/IIncidentService 

Con esto hemos sido capaces de llegar más lejos, pero el servicio caído con una excepción rara:

An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is: 
System.InvalidOperationException: An exception was thrown in a call to a WSDL export extension: System.ServiceModel.Description.XmlSerializerOperationBehavior 
contract: http://ourcompany.cs/XML:IUserServiceWCF ----> System.NullReferenceException: Object reference not set to an instance of an object. 
    at System.ServiceModel.Description.XmlSerializerMessageContractExporter.ExportFaults(Object state) 
    at System.ServiceModel.Description.MessageContractExporter.ExportMessageContract() 
    at System.ServiceModel.Description.XmlSerializerOperationBehavior.System.ServiceModel.Description.IWsdlExportExtension.ExportContract(WsdlExporter exporter, WsdlContractConversionContext contractContext) 
    at System.ServiceModel.Description.WsdlExporter.CallExtension(WsdlContractConversionContext contractContext, IWsdlExportExtension extension) 

Respuesta

1

corto la respuesta es que no se puede, por el mismo motivo que su mensaje de error, decir que no puede tener puntos finales con el mismo nombre que efectivamente está tratando de hacer. Creo que deberás hacer exactamente lo que dices que no quieres.

This might be your only option

El problema es que para especificar un servicio es utilizar XmlSerializer tiene que declarar el [XmlSerializerFormat] atributo en el servicio o en el contrato. Bueno, desde queremos utilizar el mismo para los extremos de ambos que no podemos colocarlo allí, por lo que nos queda colocarlo en el contrato . Sin embargo, cuando se reduce a , ambos puntos finales están utilizando el mismo servicio y vicariously el mismo contrato derecho?

Bueno, no tiene que ser así. Usted podría tener un contrato A derivado de contrato B, luego tener el servicio implementar el contrato A de tal manera que todo en ambos contratos sea parte del servicio.Para este ejemplo , el contrato B será nuestro contrato estándar , y el contrato A será una interfaz que solo define el atributo [XmlSerializerFormat].

Pero no puedo prometerle que funcionará con su código de cliente existente sin cambios.

+0

he actualizado mi pregunta anterior con otro intento – Sylvain

0

¿Qué hay de tener dos servicios de aplicación del mismo contrato?

igual:

class DcsService : Service 
{} 

[XmlSerializerFormat] 
class XmlService : Service 
{} 

class Service : IServiceContract 
{} 

Nunca trabajó con XmlSerializer pero usamos esta construcción para otros fines.

1

Basta con crear el objeto utilizando los [DataContract] etiquetas y [DataMember]. XmlSerializer y DataContractSerializer serializarán el objeto correctamente. Actualizaron el XmlSerializer en el marco 3.0 para gestionar la serialización del contrato de datos. DataContractSerializer puede manejar objetos [serializables] pero el comportamiento no es exacto y requiere algunos ajustes.

Simplemente hacer que todos sus objetos mediante contratos de datos. De esta forma, no tiene que preocuparse por hacer dos llamadas (una para cada una). Puede usar XmlSerializer o DataContractSerializer sin problemas.

Si es necesario agregar behavoir atributos siempre se puede añadir tanto [Serializable] y [DataContract] si lo desea.

[Serializable] 
[DataContract] 
public class Customer 

{ 
    [DataMember] 
    public int Age { get; set; } 

    [DataMember] 
    public string Name { get; set; } 

    [DataMember] 
    public int Number { get; set; } 

    [DataMember] 
    public string FullName { get; set; } 

    [XmlIgnore] 
    public int IgnoredNumber { get; set; } 
} 

XmlSerializer serializa como:

<?xml version="1.0" encoding="utf-16" ?> 
<Customer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Age>88</Age> 
    <Name>Bob</Name> 
    <Number>808</Number> 
    <FullName>Bob Jones</FullName> 
    </Customer> 

DataContractSerializer serializa como:

<?xml version="1.0" encoding="utf-8" ?> 
<Customer xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/ConsoleApplication1"> 
    <Age>88</Age> 
    <FullName>Bob Jones</FullName> 
    <Name>Bob</Name> 
    <Number>808</Number> 
    </Customer> 

Puede obviamente forzar al espacio de nombres por lo que ambos coinciden exactamente. Esto es solo por ejemplo.

Cuestiones relacionadas