2009-01-14 5 views
6

Tengo un servicio C# WCF REST que permite la adición de un marcador, enviando una solicitud HTTP POST con el marcador serializado en XML. He especificado el contrato de operación para el servicio, que toma el xml y automáticamente deserializa el objeto para mí. Mi problema es que la deserialización solo funciona correctamente si los elementos XML de la solicitud se dan en orden alfabético, y los valores de los elementos que están fuera de servicio no se rellenan.¿Pueden los servicios WCF REST admitir la deserialización de mensajes XML con un orden de elementos arbitrario?

This behaviour has been reported elsewhere.

Encuentro esto bastante insatisfactorio; Considero que el requisito de construir el XML en un orden específico es innecesario y un gran dolor de cabeza. Este es un requisito importante para agregar a todos los clientes del servicio y una fuente de problemas potencialmente difíciles de depurar.

¿Es posible dirigir WCF para que sea independiente del orden de elementos XML?


Algunos detalles adicionales para fines de aclaración:

Mi contrato de operación se ve así:

[OperationContract] 
[WebInvoke(Method="POST", UriTemplate = "/{username}/bookmarks", ResponseFormat = WebMessageFormat.Xml)] 
public void PostBookmark(string username, RestBookmark newBookmark); 

El RestMessage se ve de la siguiente manera:

[DataContract(Name = "Bookmark", Namespace = "")] 
public class RestBookmark 
{ 
    [DataMember] 
    public string BookmarkMd5 { get; set; } 

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

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

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

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

Si envío el siguiente mensaje XML, se rellenarán entonces sólo la propiedad UserName del objeto RestMessage cuando se invoca PostBookmark():

<?xml version="1.0"?><Bookmark><UserName>nick.street</UserName><Url>http://www.stackoverflow.com</Url><BookmarkMd5>f184eb3347cf94f6ce5f5fc2844e3bdd</BookmarkMd5><Description>Developer Forum</Description><Title>Stack Overflow</Title></Bookmark> 

Respuesta

1

DataContractSerializer requiere un ordenamiento estricto de los elementos tanto para el control de versiones como para el rendimiento.

Hay algunas opciones que se me ocurren,

  1. escribir un inspector mensaje a reordenar los elementos XML primas en AfterReceivedRequest antes de que sea deserialized por DataContractSerializer.

  2. utilizando el XmlSerializer para sus servicios.

  3. desarrollar HTTP proceso de mensaje XML sin formato servicio en su lugar.

  4. pasar el objeto como un diccionario (no recomendado)

+0

Me gusta la idea de usar XMLSerializer. –

+0

¡Gracias por la ayuda y la respuesta clara! –

-1

intente configurar la Orden a 0 en el atributo DataMember (para todos los miembros) :

[DataMember (Name = "Título", Orden = 0)]

+0

Gracias por la sugerencia. No ayudó desafortunadamente, parece que cuando varios artículos tienen el mismo orden vuelven a estar en orden alfabético, en lugar de "desordenados". –

0

no he tratado de hacer esto por mí mismo, pero voy a tomar una conjetura.

¿Ayudaría crear un evento [OnDeserializing] en su DataContract que se dispara justo antes de la deserialización? En ese momento, tal vez podría reordenar el xml, sin embargo, debe ordenarse para que la deserialización funcione correctamente.

Si tiene Programación de Juval Lowy WCF Servicios 2ª edición, que está cubierto partir de la página 107.

Here's the MSDN help page.

+0

Bueno, cuanto más lo miro, no estoy seguro de que puedas pasar al XML en ese momento, pero tal vez puedas usar el gancho de alguna manera ... –

0

Si no se va a especificar Order en su atributo DataMember para reflejar el orden de los nodos, entonces debe alfabetizar los nodos en su xml.

Cuestiones relacionadas