2010-09-27 18 views
15

Intenté llamar a un método WebInvoke llamado Register which returns takes en un objeto User e inmediatamente devolvió ese objeto. Se parece a lo siguiente:¿Qué significa agregar nombre y espacio de nombre a DataContract?

User Register(User user) 
{ 
    return user; 
} 

No estoy seguro de lo que los atributos de espacio de nombres Nombre y hacen que el atributo DataContract al llamar http://localhost:8081/user/register por ejemplo?

La razón que pido es porque al principio tenía mi clase decorado con la DataContract atributo de la siguiente manera:

[DataContract] 
public class User 
{ 
    // Properties 
} 

Cuando abrí violinista, y le envié una solicitud POST, que dicho método no permitido, pero cuando Cambié DataContract a:

[DataContract(Name="User", Namespace="")] 

Funcionó.

Respuesta

6

Estas propiedades controlan el espacio de nombres y el nombre del elemento en el WSDL. La parte importante en su código es Namespace="": esto anulará el espacio de nombre predeterminado (http://tempuri.org) y establecerá su valor en una URL vacía.

Al final, la clase de Usuario cambiará de nombre en WSDL de http://tempuri.org/User a simplemente Usuario.

+0

Pero, ¿cómo funciona? Quiero decir, ¿por qué dice que el método no está permitido cuando el espacio de nombres es http://tempuri.org/User en lugar de User? – Xaisoft

0

Basado en otra pregunta y sigue:

No estoy seguro de lo que el nombre y atributos de espacio de nombres hacen al atributo DataContract al llamar http://localhost:8081/user/register por ejemplo?

Le sugiero que esté utilizando el servicio REST. Cuando llamó al servicio sin configurar el Espacio de nombres para vaciar la cadena, ¿definió el XML del usuario con el espacio de nombres xmlns = "http://tempuri.org"? Si no, envió al servicio un "tipo de datos" diferente/desconocido y probablemente sea el motivo del error devuelto.

9

Respuesta de Johann, IMO es la correcta.

Funciona de esta manera porque cuando envía mensajes SOAP, los elementos deben ser calificados para el espacio de nombres, de lo contrario WCF no sabe cómo deserializar el SOAP en el contrato de datos de usuario debido a la discrepancia en el espacio de nombres.

En C#, estos dos objetos son diferentes porque están en diferentes espacios de nombres ...

namespace UserServices 
{ 
    public class User 
    { 
     public string FirstName { get; set; } 
    } 
} 

namespace TempuriServices 
{ 
    public class User 
    { 
     public string FirstName { get; set; } 
    } 
} 

el espacio de nombres en XML/SOAP tiene el mismo propósito, para asegurarse de que los objetos son del mismo cuerpo" "/" compañía "/" organización "/" dominio "etc.

Por lo que he encontrado, cuando construyo servicios SOAP, tiendo a mantener todos mis contratos de datos, contratos de servicio y espacios de nombres vinculantes en el mismo espacio de nombres, por ejemplo "http://mycompany.com/services/serviceName"

aquí están algunos grandes recursos ... Datos del Contrato de equivalencia =>http://msdn.microsoft.com/en-us/library/ms734767.aspx contrato datos de versiones de Buenas Prácticas =>http://msdn.microsoft.com/en-us/library/ms733832.aspx

espero que esto ayude.

+1

Encuentro que es mejor colocar mis contratos de servicio, incluidas las operaciones en un espacio de nombres, y mis objetos de datos en otro espacio de nombres (generalmente solo agregar 'datos') después de él.Esto se debe a que el espacio de nombres del servicio base tiene algunas palabras reservadas con las que podrías chocar inadvertidamente - methodnameResponse viene a la mente. –

14

Además de las otras respuestas, el espacio de nombres en un DataContract permite dos objetos del mismo nombre en diferentes espacios de nombres, es decir, control de versiones.

Estos dos objetos se les permite existir como diferentes propiedades en un WSDL y se darán a conocer los tipos deserializable siempre que tengan diferentes espacios de nombres:

[DataContact(Namespace = "http://myservice/v1/thing")] 
V1.Thing 

[DataContact(Namespace = "http://myservice/v2/thing")] 
V2.Thing 

Por supuesto, tienen que existir en su código C#, así como para es válido O, alternativamente, puede cambiar el nombre para que los objetos se conozcan utilizando el atributo Nombre para mayor claridad.

[DataContact(Name = "Thing")] 
V1.Thing 

[DataContact(Name= = "newThing")] 
V2.Thing 

puede utilizar esta clase cuando el nombre ha cambiado en su proyecto, pero hay que apoyar a los clientes existentes que utilizan los 'viejos nombres.

En resumen, las propiedades de nombre y espacio de nombres controlan cómo se serializarán y deserializarán los objetos cuando se transmiten a través del cable. Cuando los configura, está controlando cómo verá el cliente su contrato de datos.

+0

Consulte también: [¿Cuál es el formato de la propiedad DataContractAttribute.Namespace?] (Http://stackoverflow.com/q/22516894/2271552) – Gerrit

1

Además de otras respuestas, intentaré agregar lo que sé sobre este tema. En resumen, ambos sobrescriben el nombre y el espacio de nombre predeterminados de [DataContract] y [DataMember] (Name) con lo que proporcione a estas propiedades. De acuerdo con la documentación de la MS para la propiedad DataContractAttribute.Namespace (se llaman propiedades del atributo, no atributo), en la sección 'Sugerencia' indica link, "Para que los datos se transmitan con éxito, el nombre de los datos en un contrato de datos debe ser el mismo tanto en el cliente como en el servidor. Los proyectos de Visual Basic, de forma predeterminada, agregan un prefijo al espacio de nombre definido en cada archivo (llamado "espacio de nombres raíz", nombrado después del proyecto). Agregar este prefijo hace que los espacios de nombres del cliente y del servidor sean diferentes para el mismo tipo. La solución es establecer la propiedad del Espacio de nombres en "", o establecer explícitamente el espacio de nombres del contrato de datos en esta propiedad. " Según lo que he entendido, para que el atributo DataContract pueda serializar/deserializar los datos, los datos deben tener un espacio de nombres coincidente tanto en el cliente como en el servidor, lo que podría no ser el caso en una situación real. Por ejemplo, sus datos en el lado del servidor, si se nombran de una manera legible y sensible, pueden estar bajo el espacio de nombres que tiene un nombre algo así como "NameOfTheSolution.Server.NameOfTheProject", mientras que en el lado del cliente, podría ser algo así como " NameOfTheSolution.Client.NameOfTheProject ". Debido al espacio de nombres diferente en el que están los DataContracts, el atributo [DataContract] no podrá serializar/deserializar los datos entre el cliente y el servidor. No estoy seguro, pero esta podría ser la razón por la que dicho método no está permitido en su caso, debido a un espacio de nombres no coincidentes. En una situación en la que los espacios de nombres no coinciden, la propiedad 'Espacio de nombres' podría usarse mientras se usa el atributo [DataContract] y proporcionar la clase en ambos lados (cliente/servidor) con el mismo espacio de nombres, aunque físicamente estén en espacios de nombres diferentes.

[DataContract (Namespace = “Whatever you want, usually uri”)] 
public class User 
{} 

En cuanto a la propiedad ‘Nombre’ del atributo [DataContract] va, que prevalece sobre el nombre de su DataContract con el nombre que proporcione a esta propiedad. Un uso de esto, en el contexto del atributo DataMember es sobrecargar un método dentro de un contrato de datos. Un DataContract no permite dos DataMember con el mismo nombre, por lo que en ese escenario, la propiedad 'Name' es útil.

Cuestiones relacionadas