C#/ Java - 从Android模拟器中使用WCF服务

时间:2013-11-26 09:20:39

标签: c# java android wcf web-services

我正在尝试学习Android如何与WCF(C#)服务进行交互。我在SO上经历了很多关于同样的帖子。但是,我找不到问题的明确答案。每个人都发布了自己的方法,让我感到困惑。

我创建了一个演示服务,只返回字符串“Hello World !!”。

    public string HelloWorld()
    {
        return ("Hello World!");
    } 

我已将服务合约定义为:

    [OperationContract]
    [XmlSerializerFormat(Style = OperationFormatStyle.Document, Use = OperationFormatUse.Literal)]
    [WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Xml, 
        ResponseFormat = WebMessageFormat.Xml, UriTemplate = "/GetMessage")]
    string HelloWorld();

该服务在http://localhost:32444/Service1.svc上正常运作。

现在,从Android我尝试使用以下代码来使用该服务。

public class MainActivity extends Activity {
    /**
     * Called when the activity is first created.
     */

    private final static String SERVICE_URI = "http://10.0.2.2:32444/Service1.svc";
    TextView textView;
    Button btnShow;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        textView = (TextView) findViewById(R.id.textView);
        btnShow = (Button) findViewById(R.id.btnShow);

        btnShow.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View arg0){

                try {

                    DefaultHttpClient httpClient = new DefaultHttpClient();
                    HttpGet request = new HttpGet(SERVICE_URI + "/GetMessage");

                    request.setHeader("Accept", "application/xml");
                    request.setHeader("Content-type", "application/xml");

                    HttpResponse response = httpClient.execute(request);

                    HttpEntity responseEntity = response.getEntity();
                    String output = EntityUtils.toString(responseEntity);

                    //Toast.makeText(getApplicationContext(), output, Toast.LENGTH_SHORT).show();
                    textView.setText(output);


                } catch (Exception e) {
                    e.printStackTrace();
                    Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
                }
                }
        });
    }
}

模拟器不显示输出。我检查使用Toast消息,返回为null。错误是由于“HTTP1.1 / 400错误请求”,我在调试时遇到。

有人可以指导我吗?此外,如果方法/概念是错误的,请指出我的错误并提供解释。

提前感谢所有人!

从WCF服务库: Service1.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace WcfServiceAndroid
{
    /* NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name 
     * "Service1" in both code and config file together.*/
    public class Service1 : IService1
    {
        public string HelloWorld()
        {
            return ("Hello World!");
        }

        //public string[] NumberWorld()
        //{
        //    string[] arr= {"1","2","3","4","5"};
        //    return arr;
        //}

        public string GetData(int value)
        {
            return string.Format("You entered: {0}", value);
        }

        public CompositeType GetDataUsingDataContract(CompositeType composite)
        {
            if (composite == null)
            {
                throw new ArgumentNullException("composite");
            }
            if (composite.BoolValue)
            {
                composite.StringValue += "Suffix";
            }
            return composite;
        }
    }
}

IService1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.ServiceModel.Web;

namespace WcfServiceAndroid
{
    /* NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name 
    "IService1" in both code and config file together.*/
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        string GetData(int value);

        [OperationContract]
        //[WebGet(UriTemplate = "/GetMessage", BodyStyle = WebMessageBodyStyle.WrappedRequest,
          //      ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
        [XmlSerializerFormat(Style = OperationFormatStyle.Document, Use = OperationFormatUse.Literal)]
        [WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Xml,
            Method = "GET", ResponseFormat = WebMessageFormat.Xml, UriTemplate = "/GetMessage")]
        string HelloWorld();

        //[OperationContract]
        //string[] NumberWorld();

        [OperationContract]
        CompositeType GetDataUsingDataContract(CompositeType composite);

        // TODO: Add your service operations here
    }

    // Use a data contract as illustrated in the sample below to add composite types to service operations
    [DataContract]
    public class CompositeType
    {
        bool boolValue = true;
        string stringValue = "Hello ";

        [DataMember]
        public bool BoolValue
        {
            get { return boolValue; }
            set { boolValue = value; }
        }

        [DataMember]
        public string StringValue
        {
            get { return stringValue; }
            set { stringValue = value; }
        }
    }
}

App.config中:

<?xml version="1.0"?>
<configuration>

  <system.web>
    <compilation debug="true"/>
  </system.web>
  <!-- When deploying the service library project, the content of the config file must be added to the host's 
  app.config file. System.Configuration does not support config files for libraries. -->
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="NewBindingAndroid"/>
      </basicHttpBinding>
    </bindings>
    <services>
      <service name="WcfServiceAndroid.Service1">
        <endpoint address="" binding="basicHttpBinding" bindingConfiguration=""
          contract="WcfServiceAndroid.IService1">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://<domain>:<port>/WcfServiceAndroid/Android/" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, 
          set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="True"/>
          <!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="False"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

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

从服务应用程序: web.config中:

<?xml version="1.0"?>
<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>      

Service1.svc

<%@ ServiceHost Language="C#" Debug="true" Service="WcfServiceAndroid.Service1"%>

3 个答案:

答案 0 :(得分:0)

尝试访问

http://localhost:32444/Service1.svc/GetMessage 

从浏览器中检查它是否正常工作。

答案 1 :(得分:0)

尝试grub wsdl信息并在生成的类之间构建客户端。为java找到像“svcutils”这样的工具。 另外,您可以通过连接设置和验证进行错误。

答案 2 :(得分:0)

而不是localhost,你应该使用10.0.2.2。因为localhost不是您的计算机。这是你的android模拟器。如果仍然无法连接,请尝试编辑您的iis配置。

在您的用户文档&gt; IISExpress&gt; applicationhost.config编辑你的wcf服务项目绑定信息。它是这样的:bindingInformation =“:21422:localhost” 你应该删除localhost,应该是这样的:bindingInformation =“:21422:”

要清楚你的连接地址是http:// 10.0.2.2:port/svcfile /...

我希望它有效

编辑:您必须以管理员权限运行visual studio(以管理员身份运行)