簡體   English   中英

使用SOAP將字符串數組從ASP.NET Web服務返回到Android客戶端

[英]Return an Array of Strings from an ASP.NET Web Service to an Android client using SOAP

我想將字符串數組返回到我的Android客戶端並填充ListView。 我正在使用SOAP庫(org.ksoap2。*)來調用ASP.NET Web服務。

這是Web服務的代碼:

1. ASP Web服務

    Imports ...
    Imports System.Web.Services
    Imports System.Web.Services.Protocols
    Imports ...

    <WebService(Namespace:="...")>_
    <WebService(ConformsTo:=...)> _
    <Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _

    Public Class EnquiryWS
        Inherits System.Web.Services.WebService

    ' Web method
           <WebMethod()> _
           Public Function GetList() As String()
                  'Hardcoded list
                  Return New String() { "item1", "item2", "item3" }
           End Function

我已經通過訪問asmx測試了Web服務,沒有運行時錯誤。 我還用一個簡單的字符串對其進行了測試,Web服務將該字符串返回給Android。 像這樣:

    ' Web method
    <WebMethod()> _
    Public Function GetString() As String
           Return "My string."
    End Function

2. Android活動

其次,這是我的Android代碼,正在調用ASP.NET Web服務。

    import org.ksoap2.SoapEnvelope;
    import org.ksoap2.serialization.SoapObject;
    import org.ksoap2.serialization.SoapPrimitive;
    import org.ksoap2.serialization.SoapSerializationEnvelope;
    import org.ksoap2.transport.HttpTransportSE;

    public class MainActivity extends AppCompatActivity {

           private ArrayList<String> list;
           private ListView listview;
           private ArrayAdapter<String> adapter;

           @Override
           protected void onCreate(Bundle savedInstanceState) {
                     //...
                     new GetPersonList().execute("AsyncTask String");
                     //...
           }

           // Inner AsyncTask class
           private class GetPersonList extends AsyncTask<String,  Integer,String> {
                   private static final String SOAP_ACTION = "https://myNamespace/GetList";
                   private static final String METHOD_NAME = "GetList";
                   private static final String NAMESPACE = "https://myNamespace/";
                   private static final String URL =
            "https://myIISsite/myASMXfile.asmx";

                   @Override
                   protected void onPreExecute() {
                             super.onPreExecute();
                             // onPreExecute stuff
                   }

                   @Override
                   protected String doInBackground(String... arg) {
                             String result = null;

                             SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

                             //Create envelope
                             SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);

                             //Required for .net
                             envelope.dotNet = true;

                             //Set output SOAP object
                             envelope.setOutputSoapObject(request);

                             //Create HTTP call object
                             HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);

                             try {
                                  //Invoke web service
                                  androidHttpTransport.call(SOAP_ACTION, envelope);

                                  //Get the response
                                  SoapPrimitive response = (SoapPrimitive) envelope.getResponse();
                                  //Assign it to response to a static variable
                                  result = response.toString();
                             } catch (Exception e) {
                                  result = "error " + e.getMessage();
                             }

                             return result;
                   }

                   @Override
                   protected void onPostExecute(String result) {
                             System.out.println("Returned SOAP XML: " + result);
                             MyFunction(result);
                   }
           }
    }

MyFunction是我創建的用於執行其他一些工作的方法。

3. MyFunction

這是MyFunction方法代碼:

    public void MyFunction(String s) {
           // Add Webservice response to list
           list.add(s);

           // Set adapter
           adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item1, list);
           listview.setAdapter(adapter);

    }

我傳遞給MyFunction的參數是SOAP響應,然后將其添加到列表中並設置適配器。

好的,因此Web服務正在返回一個字符串數組,但是重寫的 onPostExecute方法正在處理一個字符串,如果我將onPostExecute參數聲明為Collection,則顯然不再重寫。

這是我在logcat中遇到的錯誤:

    Return SOAP XML: error expected: START_TAG {http://schemas.xmlsoap.org/soap/envelope/}Envelope (position:START_TAG <html>@1:7 in java.io.InputStreamReader@4182d238)

有人可以建議嗎?

我找到了解決方案。 我將響應轉換為SoapObject而不是SoapPrimitive,其原因是因為SoapPrimitive用於原始數據類型,所以SoapObject支持復合數據類型。 因此,我將數組轉換為SoapObject,而不是SoapPrimitive。

我刪除了MyFunction()方法,因為我通過重寫run()在onPostExecute()方法中設置了適配器。 最后,我添加了一個ProgressDialog,在處理時在onPreExecute()方法中顯示ProgressDialog,然后在onPostExecute()方法中調用dismiss()。

    private class GetPersonList extends AsyncTask<Void, Void, String> {

    private static final String SOAP_ACTION = "http://myNamespace/myMethod";
    private static final String METHOD_NAME = "myMethod";
    private static final String NAMESPACE = "http://myNamespace/";
    private static final String URL =
            "http://myURL/myAsmxFile.asmx";

    ProgressDialog progressDialog;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        progressDialog= ProgressDialog.show(MainActivity.this,
                "Wait",
                "Retrieving data",
                true
        );
    }

    @Override
    protected String doInBackground(Void... params) {
        String finalResult = null;

        //Create request object
        SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

        //Create envelope to which we add our request object
        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
                SoapEnvelope.VER11);

        //Required for .net
        envelope.dotNet = true;

        //Add the request object to the envelope
        envelope.setOutputSoapObject(request);

        //Create HTTP call object
        HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);

        try {
            //Invoke web service
            androidHttpTransport.call(SOAP_ACTION, envelope);

            // Get the response
            // Cast as SoapObject and not SoapPrimitive
            SoapObject response = (SoapObject) envelope.getResponse();

            //Assign it to response to a static variable
            finalResult = response.toString();

            // Now loop through the response (loop through the properties)
            // and add them to the list
            for(int i = 0; i < response.getPropertyCount(); i++) {
                list.add(response.getProperty(i).toString());
            }

        } catch (Exception e) {
            System.out.println("######## ERROR " + e.getMessage());
        }

        return finalResult;
    }

    @Override
    protected void onPostExecute(String str) {
        progressDialog.dismiss();
        System.out.println("Returned SOAP XML: " + str);

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                // Set adapter
                adapter = new ArrayAdapter<String>(MainActivity.this, R.layout.list_item, R.id.product_name, list);

                listview.setAdapter(adapter);
            }
        });
    }
}

我聽說有另一種使用Gson / Json進行此操作的方法,一旦我弄清楚了,我將發布它。

切爾茲

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM