如何通过 JSON 请求从 fiddler 调用 wcf restful 服务?

Posted

技术标签:

【中文标题】如何通过 JSON 请求从 fiddler 调用 wcf restful 服务?【英文标题】:how to call wcf restful service from fiddler by JSON request? 【发布时间】: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();

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

谢谢。

【问题讨论】:

【参考方案1】:

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

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

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

public class ***_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)。

以上是关于如何通过 JSON 请求从 fiddler 调用 wcf restful 服务?的主要内容,如果未能解决你的问题,请参考以下文章

如何从命令行使用 JSON 有效负载进行 HTTP 请求/调用?

如何使用Fiddler2模拟POST和Get提交数据

如何使用 Chainlink api 调用通过 api 从 json 返回中检索字符串值

通过 Reactjs 以 Json 格式发布请求

如何通过抓包工具fiddler获取java程序的http请求

如何通过抓包工具fiddler获取java程序的http请求