2011-08-14 12 views
6

Soy nuevo en el servicio de descanso wcf. No pude encontrar el problema que era, por qué mi servicio de descanso wcf dar 'mala solicitud'. Yo uso .NET 4.0.cómo llamar a wcf restful service de fiddler por solicitud JSON?

Mi servicio es:

[OperationContract(Name="Add")] 
[WebInvoke(UriTemplate = "test/", Method = "POST", 
      ResponseFormat=WebMessageFormat.Json, 
      RequestFormat=WebMessageFormat.Json)] 
public int Add(Number n1) 
{ 
    res = Convert.ToInt32(n1.Number1) + Convert.ToInt32(n1.Number2); 
    return res; 
} 

datos son ..

[Serializable] 
    public class Number 
    { 
     public int Number1 { get; set; } 
     public int Number2 { get; set; } 
    } 

Cuando llamo desde su regreso violinista 'HTTP/1.1 400 Bad Request'

El encabezado de mi solicitud de violinista es:

User-Agent: Fiddler 
Host: localhost:4217 
Content-Type: application/json; charset=utf-8 

y Solicitud cuerpo es:

{"Number1":"7","Number2":"7"} 

Y la respuesta de cabecera es:

HTTP/1.1 400 Bad Request 
Server: ASP.NET Development Server/10.0.0.0 
Date: Sun, 14 Aug 2011 18:10:21 GMT 
X-AspNet-Version: 4.0.30319 
Content-Length: 5450 
Cache-Control: private 
Content-Type: text/html 
Connection: Close 

Pero si llamo a este servicio por el programa # C del cliente es aceptable.

Mi código de cliente es:

uri = "http://localhost:4217/Service1.svc/"; 
Number obj = new Number() { Number1 = 7, Number2 = 7 }; 
using (HttpResponseMessage response = new HttpClient().Post(uri+"test/", 
     HttpContentExtensions.CreateDataContract(obj))) 
{ 
    string res = response.Content.ReadAsString(); 
    return res.ToString(); 
} 

favor me ayude ........

Gracias.

Respuesta

8

La forma en que se dará cuenta el problema con su código es enable tracing en el servidor , y tendrá una excepción que explica el problema. Me escribió una prueba sencilla con su código, y tenía un error similar (400), y las huellas tenía el siguiente error:

The data contract type 'WcfForums.StackOverflow_7058942+Number' cannot be 
deserialized because the required data members '<Number1>k__BackingField, 
<Number2>k__BackingField' were not found. 

tipos de datos que llevan [Serializable] serializar todas las campos en el objeto, no propiedades.Comentando ese atributo, el código realmente funciona bien (el tipo luego cae en el "poco" (Plain Old CLR Object) regla, que serializa todos los campos y propiedades públicas.

public class StackOverflow_7058942 
{ 
    //[Serializable] 
    public class Number 
    { 
     public int Number1 { get; set; } 
     public int Number2 { get; set; } 
    } 
    [ServiceContract] 
    public class Service 
    { 
     [OperationContract(Name = "Add")] 
     [WebInvoke(UriTemplate = "test/", Method = "POST", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)] 
     public int Add(Number n1) 
     { 
      int res = Convert.ToInt32(n1.Number1) + Convert.ToInt32(n1.Number2); 
      return res; 
     } 
    } 
    public static void Test() 
    { 
     string baseAddress = "http://" + Environment.MachineName + ":8000/Service"; 
     ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress)); 
     host.AddServiceEndpoint(typeof(Service), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior()); 
     host.Open(); 
     Console.WriteLine("Host opened"); 

     WebClient c = new WebClient(); 
     c.Headers[HttpRequestHeader.ContentType] = "application/json; charset=utf-8"; 
     c.Encoding = Encoding.UTF8; 
     Console.WriteLine(c.UploadString(baseAddress + "/test/", "{\"Number1\":\"7\",\"Number2\":\"7\"}")); 

     Console.Write("Press ENTER to close the host"); 
     Console.ReadLine(); 
     host.Close(); 
    } 
} 
2

Una cosa que está haciendo mal es el formato del objeto de solicitud. Chang a:

{ n1: { "Number1":"7","Number2":"7"} } 

Los nombres de los parámetros son los nombres de las propiedades de la raíz del objeto JSON se pasa a un punto final WCF JSON.

Tengo sample wcf service en git. Entre otras cosas, tiene un punto final json y en el Default.asmx uso jquery para hacer una llamada a él. Sugeriría que construyes una página web similar (la alojes en el mismo sitio web que el servicio WCF) que llame a tu servicio json a través de jquery y pruebes el servicio con eso mientras se ejecuta fiddler para obtener una solicitud de muestra. Esto será más fácil y menos propenso a errores que la construcción de la solicitud, ya que jquery se encargará de muchos detalles en el encabezado.

El código jquery ajax ejemplo para llamar a mi servicio de eco que se puede adaptar para su servicio es el siguiente:

$("#btnEchoString").click(function() { 
     var request = $("#request"); 
     var response = $("#response"); 
     $.ajax({ 
      url: 'EchoService.svc/JSON/Echo', 
      type: "POST", 
      contentType: "application/json; charset=utf-8", 
      data: JSON.stringify({ request: request.val() }), 
      dataType: "json", 
      success: function (data) { 
       response.val(data.d); 
      }, 
      error: function (request, status, error) { 
       //TODO: do something here 
      } 
     }); 
    }); 
+1

El uso "normal" de WCF REST es utilizar el comportamiento '' (o 'WebHttpBehavior', si es por código), no el' 'que tiene en su muestra. Para , el BodyStyle predeterminado es' Bare', lo que significa que no es necesario envolver el objeto en un objeto JSON con el nombre del parámetro (el valor predeterminado para es 'WrappedRequest'). – carlosfigueira

+0

Carlos, ¡gracias por la aclaración! –