问题描述
我想学习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 =http://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;
< DNS值=本地主机/>
< /身份>
< /端点>
<端点地址=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您的计算机。这是你的Android模拟器。如果你仍然无法连接,尝试编辑您的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服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!