无法使用 Android 客户端 POST 到 WCF 服务

发布于 2024-11-08 01:24:04 字数 2738 浏览 0 评论 0原文

我有一个正在运行的自托管 WCF Web 服务和一个 Android 客户端应用程序。我能够以 json 格式从 Web 服务获取或检索数据,但是无法向服务器 POST 或发送任何数据。

下面是来自 WCF 服务的代码:

 [OperationContract]
 [WebInvoke(Method = "POST",
 UriTemplate = "/SetValue",
 RequestFormat = WebMessageFormat.Json,
 ResponseFormat = WebMessageFormat.Json,
 BodyStyle = WebMessageBodyStyle.Wrapped)]
 public string SetValue(TestClass someValue)
 {
     return someValue.Something.ToString();
 }

[DataContract]
public class TestClass
{
    [DataMember(Name = "something")]
    public int Something
    {
        get;
        set;
    }
}

下面是来自 Android 客户端的代码:

 HttpClient httpClient = new DefaultHttpClient();
 HttpPost request = new HttpPost("http://xxx.xxx.x.x:8000/SetValue");
 List<NameValuePair> params = new ArrayList<NameValuePair>(1);
 params.add(new BasicNameValuePair("something", "12345"));
 request.setEntity(new UrlEncodedFormEntity(params));
 HttpResponse response = httpClient.execute(request);

以下是我启动自托管服务的方式:

 class Program
 {
    static void Main()
    {
        Uri baseAddress = new Uri("http://localhost:8000/");

        using (WebServiceHost host = new WebServiceHost(typeof(ServerSideProfileService), baseAddress))
        {
            host.AddServiceEndpoint(typeof(ServerSideProfileService), new BasicHttpBinding(), "Soap");
            ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(ServerSideProfileService), new WebHttpBinding(), "Web");
            endpoint.Behaviors.Add(new WebHttpBehavior());

            // Open the service host, service is now listening
            host.Open();
        }
     }
  }

我只有一个 app.config,其中包含:

 <?xml version="1.0"?>
 <configuration>
 <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>

我运行时收到的响应来自 Android 客户端的 httpClient.execute(request) 包括:

 HTTP/1.1 400 Bad Request
 Request Error
 The server encountered an error processing the request. See server logs for more details.

差不多就是这样了。我对 WCF 很陌生,不知道这个“服务器日志”在哪里,并且不知道如何解决或调试这个问题? (我尝试过 Fiddler2,但它似乎没有检测到来自 Android 客户端的任何内容。)

[编辑]

我也尝试过,

 JSONObject json = new JSONObject(); 
 json.put("something", "12345"); 
 StringEntity entity = new StringEntity(json.toString()); 
 entity.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
 entity.setContentType( new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));  
 request.setEntity(entity); 

这也会导致错误。

我还注意到,如果我更改“SetValue”以返回一个常量,例如“abcd”,而不是 someValue.Something.ToString(),那么一切正常吗?

I have a self-hosted WCF web service running, and an Android client application. I am able to GET or retrieve data from the web service in json format, however I am unable to POST or send any data to the server.

Below is the code from the WCF service:

 [OperationContract]
 [WebInvoke(Method = "POST",
 UriTemplate = "/SetValue",
 RequestFormat = WebMessageFormat.Json,
 ResponseFormat = WebMessageFormat.Json,
 BodyStyle = WebMessageBodyStyle.Wrapped)]
 public string SetValue(TestClass someValue)
 {
     return someValue.Something.ToString();
 }

[DataContract]
public class TestClass
{
    [DataMember(Name = "something")]
    public int Something
    {
        get;
        set;
    }
}

Below is the code from the Android client:

 HttpClient httpClient = new DefaultHttpClient();
 HttpPost request = new HttpPost("http://xxx.xxx.x.x:8000/SetValue");
 List<NameValuePair> params = new ArrayList<NameValuePair>(1);
 params.add(new BasicNameValuePair("something", "12345"));
 request.setEntity(new UrlEncodedFormEntity(params));
 HttpResponse response = httpClient.execute(request);

The following is how I start the self-hosted service:

 class Program
 {
    static void Main()
    {
        Uri baseAddress = new Uri("http://localhost:8000/");

        using (WebServiceHost host = new WebServiceHost(typeof(ServerSideProfileService), baseAddress))
        {
            host.AddServiceEndpoint(typeof(ServerSideProfileService), new BasicHttpBinding(), "Soap");
            ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(ServerSideProfileService), new WebHttpBinding(), "Web");
            endpoint.Behaviors.Add(new WebHttpBehavior());

            // Open the service host, service is now listening
            host.Open();
        }
     }
  }

I only have an app.config which just has:

 <?xml version="1.0"?>
 <configuration>
 <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>

The response I'm getting when I run httpClient.execute(request) from the Android client includes:

 HTTP/1.1 400 Bad Request
 Request Error
 The server encountered an error processing the request. See server logs for more details.

And that's pretty much it. I am very new to WCF and don't know where this 'server log' would be, and am at a loss as to how to troubleshoot or debug this? (I have tried Fiddler2 but it doesn't seem to detect anything from the Android client.)

[EDIT]

I have also tried

 JSONObject json = new JSONObject(); 
 json.put("something", "12345"); 
 StringEntity entity = new StringEntity(json.toString()); 
 entity.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
 entity.setContentType( new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));  
 request.setEntity(entity); 

which also results in the error.

I also noticed that if I change 'SetValue' to return a constant, such as "abcd", instead of someValue.Something.ToString(), then everything works?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

情独悲 2024-11-15 01:24:04

您的客户端代码正在发送 html 表单 post 格式的有效负载,但您的服务器需要 json 有效负载,您需要客户端类似于

HttpClient httpClient = new DefaultHttpClient();
HttpPost request = new HttpPost("http://xxx.xxx.x.x:8000/SetValue");
StringEntity e = new StringEntity("{ \"something\":12345 }", "UTF-8");
request.setEntity(e);
request.setHeader("content-type", "application/json");
HttpResponse response = httpClient.execute(request);

Your client code is sending a html form post formatted payload, but your server is expecting a json payload, you need the client to be something like

HttpClient httpClient = new DefaultHttpClient();
HttpPost request = new HttpPost("http://xxx.xxx.x.x:8000/SetValue");
StringEntity e = new StringEntity("{ \"something\":12345 }", "UTF-8");
request.setEntity(e);
request.setHeader("content-type", "application/json");
HttpResponse response = httpClient.execute(request);
你的往事 2024-11-15 01:24:04

我遇到了同样的问题,我通过

BodyStyle = WebMessageBodyStyle.WrappedRequest

从 WCF 方法标头中

 [WebInvoke(Method = "POST", UriTemplate = "mymethod", RequestFormat=WebMessageFormat.Json,
            BodyStyle = WebMessageBodyStyle.WrappedRequest,
                ResponseFormat=WebMessageFormat.Json)]

删除
解决了这个问题更改为

 [WebInvoke(Method = "POST", UriTemplate = "mymethod", RequestFormat=WebMessageFormat.Json,
                ResponseFormat=WebMessageFormat.Json)]

I had the same problem, I resolved this by removing

BodyStyle = WebMessageBodyStyle.WrappedRequest

from my WCF method header

 [WebInvoke(Method = "POST", UriTemplate = "mymethod", RequestFormat=WebMessageFormat.Json,
            BodyStyle = WebMessageBodyStyle.WrappedRequest,
                ResponseFormat=WebMessageFormat.Json)]

Changed to

 [WebInvoke(Method = "POST", UriTemplate = "mymethod", RequestFormat=WebMessageFormat.Json,
                ResponseFormat=WebMessageFormat.Json)]
北恋 2024-11-15 01:24:04
    [WebInvoke(UriTemplate = "crud/delete",
        ResponseFormat = WebMessageFormat.Json,
        RequestFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.WrappedRequest,
        Method = "POST"
    )]        
    public SampleItem Delete(string id)
    {
        SampleItem item = new SampleItem();
        item.Id = 118;
        item.StringValue = id;
        return item;
        throw new NotImplementedException();
    }


var params  = '{"id":"sfs"}';

function postTest0(){
    $.ajax({
        url:'http://localhost/wcfrest/rest/crud/delete',
        //url:'http://localhost/wcfrest/rest/crud/create', //后台处理程序
        type:'post',    //数据发送方式
        dataType:'json', //接受数据格式
        contentType: "application/json",
        data:params, //要传递的数据
        timeout:1000,
        error:function(){alert('post error');},
        success:update_page //回传函数(这里是函数名)
    });
}

superfell那个正解!

    [WebInvoke(UriTemplate = "crud/delete",
        ResponseFormat = WebMessageFormat.Json,
        RequestFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.WrappedRequest,
        Method = "POST"
    )]        
    public SampleItem Delete(string id)
    {
        SampleItem item = new SampleItem();
        item.Id = 118;
        item.StringValue = id;
        return item;
        throw new NotImplementedException();
    }


var params  = '{"id":"sfs"}';

function postTest0(){
    $.ajax({
        url:'http://localhost/wcfrest/rest/crud/delete',
        //url:'http://localhost/wcfrest/rest/crud/create', //后台处理程序
        type:'post',    //数据发送方式
        dataType:'json', //接受数据格式
        contentType: "application/json",
        data:params, //要传递的数据
        timeout:1000,
        error:function(){alert('post error');},
        success:update_page //回传函数(这里是函数名)
    });
}

superfell 那个正解!

别想她 2024-11-15 01:24:04

据我所知,Android 将 JSON 字符串转换为字节数组流,然后发布它。这是我自己的代码作为示例

HttpPost httpPost = new HttpPost(URL_Base + uri);
httpPost.setEntity(new StringEntity(sJSONOut));
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-type", "application/json");
HttpEntity oHttpEntity = new DefaultHttpClient().execute(httpPost).getEntity();

在 eclipse 中,当在倒数第二行设置断点并检查 httpPost 对象属性时,我发现 StringEntity 的值不是字节数组 [123. 43, 234 ......即使我已经确认我的字符串 sJSONOut 是正确格式化的 json。

这里的另一个答案建议从 WCF 方法标头中删除 BodyStyle = WebMessageBodyStyle.WrappedRequest 。这给了我线索,我需要将该行从 WrappedRequest 更改为 Bare,这就是最终的工作。

BodyStyle = WebMessageBodyStyle.Bare

From what I have found Android converts the JSON string to a byte array stream and then posts it. Here is my own code as an example

HttpPost httpPost = new HttpPost(URL_Base + uri);
httpPost.setEntity(new StringEntity(sJSONOut));
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-type", "application/json");
HttpEntity oHttpEntity = new DefaultHttpClient().execute(httpPost).getEntity();

In eclipse, when setting a break point on the second to last line and inspecting the httpPost object properties i find the value of my StringEntity is not a byte array [123. 43, 234 ...... even though I have confirmed that my string sJSONOut is correctly formatted json.

Another answer here suggested removing BodyStyle = WebMessageBodyStyle.WrappedRequest from the WCF method header. That gave me the clue I needed to change that line from WrappedRequest to Bare which is what ended up working.

BodyStyle = WebMessageBodyStyle.Bare

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文