method - servicio rest c# json
¿Por qué WCF/JSON no devuelve `null` para un valor de retorno nulo? (3)
De acuerdo con la especificación JSON , la forma correcta de representar un valor nulo es el null
literal.
Si ese es el caso, ¿por qué WCF devuelve una respuesta vacía en lugar de null
? ¿Es esto un error o este comportamiento está documentado en alguna parte?
Ejemplo de repro completo:
using System;
using System.ServiceModel;
using System.ServiceModel.Web;
[ServiceContract()]
public class Service1
{
[OperationContract(), WebGet(ResponseFormat = WebMessageFormat.Json)]
public string GetSomeString() { return "SomeString"; }
[OperationContract(), WebGet(ResponseFormat = WebMessageFormat.Json)]
public string GetNull() { return null; }
}
public class Host
{
public static void Main()
{
// Very simple WCF server
var host = new WebServiceHost(typeof(Service1), new Uri("http://localhost:8000/"));
host.AddServiceEndpoint(typeof(Service1), new WebHttpBinding() {
HostNameComparisonMode = HostNameComparisonMode.Exact
}, "");
host.Open();
Console.WriteLine("Service is running, press enter to quit...");
Console.ReadLine();
host.Close();
}
}
Resultado Esperado:
$ curl http://localhost:8000/GetSomeString && echo
"SomeString"
$ curl http://localhost:8000/GetNull && echo
null
$
Resultado actual:
$ curl http://localhost:8000/GetSomeString && echo
"SomeString"
$ curl http://localhost:8000/GetNull && echo
$
En mi opinión, WCF u otras formas son el contrato de transferencia de datos y toda la base de datos en una cadena. Diferencia de cómo se contrae la forma de cadena.
Este método simplemente devuelve una cadena, no importa cómo esté el formato, solo el cliente puede obtener los datos, por lo que no es necesario que esté en formato json.
Si solo devuelve la cadena "null"
represente null
si quiero devolver la cadena "null"
lugar de null
. Estará confundido. Por supuesto que puedes usar los caracteres de ESC resuélvelo. Tal vez piensen que nada es mejor.
Si el cliente usa datos en formato json, simplemente devuelve una cadena "null"
, luego, si la deserializa, obtendrá un null
, todo está bien. De todos modos no importa qué retorno, sino cómo contratar el formato de los datos.
Si desea que se devuelvan valores nulos reales en su respuesta wcf en formato json, debe definir un datacontract y devolverlo sin inicializarlo
[DataContract]
public class Employee
{
[DataMember]
public string id { get; set; }
}
Ahora en tu contrato de operación devuélvelo así.
[OperationContract(), WebGet(ResponseFormat = WebMessageFormat.Json)]
public string GetNull() { return new Employee(); }
Entonces anularás los valores en tu respuesta json.
Espero eso ayude
Su enlace a la especificación json incluye estas líneas interesantes:
JSON está construido sobre dos estructuras:
Una colección de pares de nombre / valor . En varios idiomas, esto se realiza como un objeto, registro, estructura, diccionario, tabla hash, lista con clave o matriz asociativa.
Una lista ordenada de valores . En la mayoría de los idiomas, esto se realiza como una matriz, vector, lista o secuencia.
Por lo tanto, a mi entender, sus tipos de devolución no se ajustan a la especificación.
Ninguna
public string GetNull() { return null; }
public string GetNull() { return null; }
ni
public string GetSomeString() { return "SomeString"; }
public string GetSomeString() { return "SomeString"; }
Para cumplir con las especificaciones, tendría que cambiarlas para que coincidan con el # 1 o el # 2.
Se utiliza una estructura.
public struct structWithNull{public object resp;}
El valor predeterminado es nulo, por lo quepublic structWithNull GetNull() {return new structWithNull() ; }
public structWithNull GetNull() {return new structWithNull() ; }
devuelve:Se usa una matriz de tamaño uno.
public object[] GetNullArray() {return new object[1] ; }
public object[] GetNullArray() {return new object[1] ; }
. El valor predeterminado es de nuevo nulo; vuelve:
Me parece que JSON se basa en encapsular datos, como XML, donde siempre se necesita un nodo principal. Así que supongo que no hay otra solución a esto como usar una estructura / clase (# 1) o una matriz (# 2).
Actualizar:
He encontrado una pista aquí: rfc7159
Tenga en cuenta que ciertas especificaciones previas de JSON restringieron un texto JSON para que fuera un objeto o una matriz. Las implementaciones que solo generan objetos o matrices para las que se solicita un texto JSON serán interoperables en el sentido de que todas las implementaciones las aceptarán como textos JSON conformes.
Si entiendo esto correctamente, tiene razón y debe devolverse el valor nulo hoy, ya que es primitivo, pero no porque el enfoque principal podría estar en el comportamiento antiguo especificado del único objeto y las versiones basadas en matrices.
Finalmente creo que solo Microsoft puede responder esta pregunta completamente.