【问题标题】:how to call wcf restful service from fiddler by JSON request?如何通过 JSON 请求从 fiddler 调用 wcf restful 服务?
【发布时间】:2011-10-26 21:36:52
【问题描述】:

我是 wcf restful 服务的新手。我找不到问题,为什么我的 wcf restful 服务给出“错误请求”。我使用 .NET 4.0。

我的服务是:

[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;
}

数据是..

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

当我从提琴手调用时,它返回“HTTP/1.1 400 Bad Request”

我的提琴手请求头是:

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

请求正文是:

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

响应头是:

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

但是如果我通过 C# 客户端程序调用这个服务就可以了。

我的客户端代码是:

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();
}

请帮帮我........

谢谢。

【问题讨论】:

    标签: c# wcf json fiddler


    【解决方案1】:

    您可以通过服务器上的enable tracing 找到代码问题的方法,它会有一个解释问题的异常。我用你的代码写了一个简单的测试,它有一个类似的错误(400),并且跟踪有以下错误:

    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.
    

    标有[Serializable] 的数据类型会序列化对象中的所有字段,而不是属性。通过注释掉该属性,代码实际上运行良好(然后该类型属于“POCO”(普通旧 Clr 对象)规则,该规则序列化所有公共字段和属性。

    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】:

      您做错的一件事是请求对象的格式。改成:

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

      参数名称是传递给 wcf json 端点的 json 对象的根属性名称。

      我在 git 上有一个 sample wcf service。除其他外,它有一个 json 端点,在 Default.asmx 我使用 jquery 来调用它。我建议您构建一个类似的网页(将其托管在与 WCF 服务相同的网站上),通过 jquery 调用您的 json 服务,并在 fiddler 运行以获取示例请求时使用该服务测试该服务。这将比自己构建请求更容易且更不容易出错,因为 jquery 会处理标头中的许多细节。

      调用我的echo服务的jquery ajax示例代码,你可以适应你的服务如下:

          $("#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
                  }
              });
          });
      

      【讨论】:

      • WCF REST 的“正常”用法是使用<webHttp/> 行为(或WebHttpBehavior,如果通过代码),而不是示例中的<enableWebScript/>。对于,默认的BodyStyle是Bare,这意味着你不需要将对象包裹在一个带有参数名称的JSON对象中(的默认是WrappedRequest)。
      猜你喜欢
      • 2013-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-08
      • 1970-01-01
      • 1970-01-01
      • 2014-04-30
      • 1970-01-01
      相关资源
      最近更新 更多