在 Android 中使用 Restful WCF 服务

Posted

技术标签:

【中文标题】在 Android 中使用 Restful WCF 服务【英文标题】:Consuming Restful WCF Service in Android 【发布时间】:2013-05-04 02:36:20 【问题描述】:

我不确定是什么导致请求无法执行。我试图在 android 中调用 WCF Restful 服务,并收到错误消息“请求错误”。看看这个例子,我看不出这个例子不应该工作的任何原因。见下文:

这是 .Net 服务:

[ServiceContract]
    public interface ISampleService
    
        [OperationContract]
        [WebInvoke(
            Method="POST", UriTemplate="/Login", BodyStyle= WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
        string Login(string value);
    

public class SampleService : ISampleService
    
        public string Login(string value)
        
            string t = "";
            try
            
                //foreach (string s in value)
                //
                //    t = s;
                //
                return t;
            
            catch (Exception e)
            
                return e.ToString();
            
        
    

Java:

package com.mitch.wcfwebserviceexample;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.protocol.HTTP;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONStringer;

import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.app.Activity;

public class MainActivity extends Activity implements OnClickListener 
    private String values ="";
  Button btn;
  TextView tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btn = (Button)this.findViewById(R.id.btnAccess);
        tv = (TextView)this.findViewById(R.id.tvAccess);
        btn.setOnClickListener(this);
    

    @Override
    public void onClick(View arg0) 
        try
        
        AsyncTaskExample task = new AsyncTaskExample(this);
        task.execute("");
        String  test = values;
        tv.setText(values);
         catch(Exception e)
        
           Log.e("Click Exception ", e.getMessage());   
        

    

    public class AsyncTaskExample extends AsyncTask<String, Void,String>
    
        private String Result="";
        //private final static String SERVICE_URI = "http://10.0.2.2:8889";
        private final static String SERVICE_URI = "http://10.0.2.2:65031/SampleService.svc";
        private MainActivity host;
        public AsyncTaskExample(MainActivity host)
        
            this.host = host;
        

        public String GetSEssion(String URL)
        
          boolean isValid = true;
          if(isValid)
          

              HttpClient client = new DefaultHttpClient();
              HttpPost post = new HttpPost("http://10.0.2.2:65031/SampleService.svc/Login");
              try
              
                List<NameValuePair> value = new ArrayList<NameValuePair>(1);
                value.add(new BasicNameValuePair("value", "123456"));
                post.setEntity(new UrlEncodedFormEntity(value));
                HttpResponse response = client.execute(post) ;
                BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
                String line ="";
                while((line = rd.readLine()) != null)
                
                    System.out.println(line);
                
              catch(Exception e)
              
                  Log.e("Error", e.getMessage());
              
         
          return Result;
        

        @Override
        protected String doInBackground(String... arg0) 
            android.os.Debug.waitForDebugger();
            String t = GetSEssion(SERVICE_URI);
            return t;
        

        @Override
        protected void onPostExecute(String result) 
        //  host.values = Result;
            super.onPostExecute(result);
        
        @Override
        protected void onPreExecute() 
            // TODO Auto-generated method stub
            super.onPreExecute();
        

        @Override
        protected void onCancelled() 
            // TODO Auto-generated method stub
            super.onCancelled();
        
    

【问题讨论】:

url 编码形式不是 JSON ... 并且服务期望获得 JSON ... 使用 new StringEntity("\"value\": \"123456\"") 而不是 UrlEncodedFormEntity ... 因为您的代码发送 value=123456 并且您需要发送"value": "123456" 我认为最好使用 URLEncodedFormatEntity 而不是 StringEntity。我使用的是 StringEntity,它对于简单的参数效果很好。但是,当 wcf 方法需要一个数组或锯齿状数组时,我收到了“请求错误”消息。例如,服务契约是这样描述的 string[][] Login(string[][] value)。我很难忍受它。 【参考方案1】:

我终于让它按照我想要的方式工作了。问题是我以这种方式构建数组(参见下面的第 1 节)并将其传递给 JSONObject 或 JSONArray。我使用 JSONArray 切换和构建 Array 并将其传递给 JSONObject(参见第 2 节)。它就像一个魅力。

Section1:错误的方法 - (如果您要查看数组并将它们放在 JSONArray 中,可能会以这种方式工作。如果可以直接完成,那就太麻烦了。)

String[][] Array = 
new String[]"Example", "Test",
new String[]"Example", "Test",
;

JSONArray jar1 = new JSONArray();
jar1.put(0, Array);

// 没用 第 2 部分:经过长时间的尝试以及来自@vorrtex 的一些非常有用的提示和提示,我做到了这一点。

**JSONArray jar1 = new JSONArray();
jar1.put(0, "ABC");
jar1.put(1, "Son");
jar1.put(2, "Niece");**

**JSONArray jarr = new JSONArray();
jarr.put(0, jar1);**

JSONArray j = new JSONArray();
j.put(0,"session");

JSONObject obj = new JSONObject();          
obj.put("value", jarr);
obj.put("test", j);
obj.put("name","myName");
Log.d("Obj.ToString message: ",obj.toString());
StringEntity entity = new StringEntity(obj.toString());

查看网络服务,它正是我想要的。

感谢您的帮助!!!!

【讨论】:

我有一个问题,我的数组列表中有多个数据,那么我如何在 jason 中解析它。我有 ID、姓名、地址、电话号码的数组列表,我想在 web 服务中传递所有数据 我使用的是二维数组。但是,您应该能够遍历列表并创建将发送到 Web 服务的 JSONObject。

以上是关于在 Android 中使用 Restful WCF 服务的主要内容,如果未能解决你的问题,请参考以下文章

将字符串从 android 传递到 wcf restful 服务变得空

Android 向 WCF RESTful WS 发布请求(JSON 参数)

如何在 RESTful WCF API 中实现 HMAC 身份验证

如何使用用户名/密码 + SSL 使用 WCF 配置安全 RESTful 服务

从 WCF 过渡 WCF RESTful [重复]

从 WCF RESTful 响应中删除 xml 命名空间