C#/ Java的 - 从消费Android模拟器WCF服务 [英] C#/Java - Consuming WCF Service from Android emulator

查看:174
本文介绍了C#/ Java的 - 从消费Android模拟器WCF服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想学习Android的如何与WCF(C#)服务交互。我已经通过关于一样的,在这里让很多帖子了。但是,我无法找到一个明确的答案的问题。每一个机构发布了自己的方法,这是混淆了我。

我创建了一个演示服务,它只是返回的字符串Hello World!

 公共字符串的HelloWorld()
    {
        返回(的Hello World!);
    }

我已经定义了服务合同为:

  [OperationContract的]
    [XmlSerializerFormat(风格= OperationFormatStyle.Document,使用= OperationFormatUse.Literal)
    [WebGet(BodyStyle = WebMessageBodyStyle.Wrapped,RequestFormat = WebMessageFormat.Xml,
        ResponseFormat = WebMessageFormat.Xml,UriTemplate =/ GetMessage函数)]
    字符串的HelloWorld();

该服务工作正常在的http://本地主机:32444 / Service1.svc

现在,在Android我试图消耗与下列code的服务。

 公共类MainActivity延伸活动{
    / **
     *当第一次创建活动调用。
     * /    私人最终静态字符串SERVICE_URI =htt​​p://10.0.2.2:32444/Service1.svc;
    TextView中的TextView;
    按钮btnShow;    @覆盖
    公共无效的onCreate(捆绑savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.main);        TextView的=(的TextView)findViewById(R.id.textView);
        btnShow =(按钮)findViewById(R.id.btnShow);        btnShow.setOnClickListener(新View.OnClickListener(){            @覆盖
            公共无效的onClick(查看为arg0){                尝试{                    DefaultHttpClient的HttpClient =新DefaultHttpClient();
                    HTTPGET请求=新HTTPGET(SERVICE_URI +/ GetMessage函数);                    request.setHeader(接受,应用程序/ XML);
                    request.setHeader(内容类型,应用程序/ XML);                    HTT presponse响应= httpClient.execute(请求);                    HttpEntity responseEntity = response.getEntity();
                    字符串输出= EntityUtils.toString(responseEntity);                    //Toast.makeText(getApplicationContext(),输出Toast.LENGTH_SHORT).show();
                    textView.setText(输出);
                }赶上(例外五){
                    e.printStackTrace();
                    Toast.makeText(getApplicationContext(),e.​​getMessage(),Toast.LENGTH_SHORT).show();
                }
                }
        });
    }
}

仿真器显示没有输出。我检查了使用吐司消息和回报null.The错误是由于HTTP1.1 / 400错误的请求,这是我碰到的同时调试。

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

感谢所有提前!

从WCF服务库:
Service1.cs:

 使用系统;
使用System.Collections.Generic;
使用System.Linq的;
使用System.Runtime.Serialization;
使用System.ServiceModel;
使用System.Text;命名空间WcfServiceAndroid
{
    / *注意:您可以使用重构菜单上的重命名命令来更改类名
     *服务1,在这两个code和配置文件一起。* /
    公共类服务1:IService1
    {
        公共字符串的HelloWorld()
        {
            返回(的Hello World!);
        }        //公共字符串[] NumberWorld()
        // {
        //串[] ARR = {1,2,3,4,5};
        //返回ARR;
        //}        公共字符串的GetData(int值)
        {
            返回的String.Format(您输入:{0},值);
        }        公众的CompositeType GetDataUsingDataContract(CompositeType中复合)
        {
            如果(复合== NULL)
            {
                抛出新的ArgumentNullException(复合);
            }
            如果(composite.BoolValue)
            {
                composite.StringValue + =后缀;
            }
            返回复合材料;
        }
    }
}

IService1.cs

 使用系统;
使用System.Collections.Generic;
使用System.Linq的;
使用System.Runtime.Serialization;
使用System.ServiceModel;
使用System.Text;
使用System.ServiceModel.Web;命名空间WcfServiceAndroid
{
    / *注意:您可以使用重构菜单上的重命名命令来更改接口名称
    IService1在这两个code和配置文件一起。* /
    [服务合同]
    公共接口IService1
    {
        [OperationContract的]
        字符串的GetData(int值);        [OperationContract的]
        // [WebGet(UriTemplate =/ GetMessage函数,BodyStyle = WebMessageBodyStyle.WrappedRequest,
          // ResponseFormat = WebMessageFormat.Json,RequestFormat = WebMessageFormat.Json)
        [XmlSerializerFormat(风格= OperationFormatStyle.Document,使用= OperationFormatUse.Literal)
        [WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped,RequestFormat = WebMessageFormat.Xml,
            方法=GET,ResponseFormat = WebMessageFormat.Xml,UriTemplate =/ GetMessage函数)]
        字符串的HelloWorld();        // [OperationContract的]
        //字符串[] NumberWorld();        [OperationContract的]
        CompositeType中GetDataUsingDataContract(CompositeType中复合材料);        // TODO:添加您的业务运营在这里
    }    //使用数据合同下面的示例中所示复合类型添加到服务操作
    [DataContract]
    公共类的CompositeType
    {
        布尔boolValue = TRUE;
        字符串stringValue的=你好;        [数据成员]
        公共BOOL BoolValue
        {
            {返回boolValue; }
            集合{boolValue =价值; }
        }        [数据成员]
        公共字符串的StringValue
        {
            {返回stringValue的; }
            集合{stringValue的=价值; }
        }
    }
}

App.config中:

 <?XML版本=1.0&GT?;
<结构>  <&的System.Web GT;
    <编译调试=真/>
  < /system.web>
  <! - 在部署该服务库项目,配置文件的内容必须添加到主机的
  app.config文件。 System.Configuration不支持配置文件库。 - >
  < system.serviceModel>
    <&绑定GT;
      <&basicHttpBinding的GT;
        <绑定名称=NewBindingAndroid/>
      < / basicHttpBinding的>
    < /绑定>
    <服务和GT;
      <服务名称=WcfServiceAndroid.Service1>
        <端点地址=绑定=basicHttpBinding的bindingConfiguration =
          合同=WcfServiceAndroid.IService1>
          <同一性GT;
            < D​​NS值=本地主机/>
          < /身份>
        < /端点>
        <端点地址=MEX绑定=mexHttpBinding合同=IMetadataExchange接口/>
        <主机>
          < baseAddresses>
            <添加baseAddress =HTTP://&LT结构域GT;:<港口> / WcfServiceAndroid / Android版//>
          < / baseAddresses>
        < /主机>
      < /服务>
    < /服务>
    <&行为GT;
      < serviceBehaviors>
        <&行为GT;
          <! - 为了避免泄露的元数据信息,
          设定值以下为false和部署之前删除上面的元数据终结点 - >
          < serviceMetadata httpGetEnabled =真/>
          <! - 要接收故障中的异常细节进行调试,
          下面设置为true值。设置为false部署之前
          以避免泄露异常信息 - >
          < serviceDebug includeExceptionDetailInFaults =FALSE/>
        < /行为>
      < / serviceBehaviors>
    < /行为>
  < /system.serviceModel><&启动GT;< supportedRuntime版本=V4.0SKU = /&GT.net框架,版本= V4.0。;< /启动>< /结构>

从服务应用程序:
Web.config文件:

 <?XML版本=1.0&GT?;
<结构>  <&的System.Web GT;
    <编译调试=真targetFramework =4.0/>
  < /system.web>
  < system.serviceModel>
    <&行为GT;
      < serviceBehaviors>
        <&行为GT;
          <! - 为了避免泄露的元数据信息,下面设置为false的价值和部署之前删除上面的元数据终结点 - >
          < serviceMetadata httpGetEnabled =真/>
          <! - 要接收故障中的异常细节进行调试,下面设置为true值。设置为false部署之前,以避免泄露异常信息 - >
          < serviceDebug includeExceptionDetailInFaults =FALSE/>
        < /行为>
      < / serviceBehaviors>
    < /行为>
    < serviceHostingEnvironment multipleSiteBindingsEnabled =真/>
  < /system.serviceModel>
 < system.webServer>
    <模块runAllManagedModulesForAllRequests =真/>
  < /system.webServer>

Service1.svc

 <%@ ServiceHost的语言=C#调试=真正的服务=WcfServiceAndroid.Service1%GT;


解决方案

而不是你应该使用本地主机10.0.2.2。因为localhost您的计算机。这是你的Andr​​oid模拟器。如果你仍然无法连接,尝试编辑您的IIS配置。

在您的用户文档> IISEx preSS>对ApplicationHost.config编辑WCF服务项目的绑定信息。它是这样的:bindingInformation =:21422:本地主机
你应该删除本地主机,应该是这样的:bindingInformation =
的:21422:

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

我希望它的工作原理

编辑:您必须运行具有管理员权限的Visual Studio(以管理员身份运行)

I'm trying to learn how Android interacts with WCF (C#) service. I have gone through a lot of posts regarding the same, here at SO. However, I couldn't find a definite answer to the problem. Every body has posted their own approach and it is confusing me.

I have created a demo service which just returns the string "Hello World!!".

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

I have defined the service contract as:

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

The service is working fine on http://localhost:32444/Service1.svc.

Now, from Android I'm trying to consume the service with the following code.

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();
                }
                }
        });
    }
}

The emulator shows no output. I checked using Toast message and the return is null.The error is due to "HTTP1.1/400 Bad Request", which I came across while debugging.

Can somebody please guide me with this? Also, if the approach/concept is wrong please point to me my mistake and provide an explanation.

Thanking all in advance!

From the WCF Service Library: 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>

From the Service application: 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"%>

解决方案

instead of localhost you should use 10.0.2.2 . Because localhost is not your computer. It is your android emulator. And if you still can't connect, try to edit your iis config.

in your user Documents > IISExpress > applicationhost.config edit your wcf service projects binding information. it is something like this : bindingInformation=":21422:localhost" and you should delete localhost and should be something like this : bindingInformation=":21422:"

to be clear your connection address is http:// 10.0.2.2:port/svcfile/...

I hope it works

edit: you have to run visual studio with administrator privileges (Run as administrator)

这篇关于C#/ Java的 - 从消费Android模拟器WCF服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆