Pull to refresh

Вызов .NET сервиса (WCF RESTful) из Android приложения

Development for Android *
Привет Хаброжители!

Вот недавно столкнулся с проблемой, нужно было вызвать .NET WCF сервис из Javа. Нашел несколько примеров, реализации, одним из них и хочу поделиться, вдруг пригодиться кому. Прогулявшись по просторам интернета, нашел готовое решение для SOAP сервисов. Разбираться с ним не стал и продолжил поиск. Затем, было найдено решение с использованием WCF RESTful сервиса, который возвращал данные в формате JSON. Решил разобраться подробнее и попробовать как это работает.



Итак, для начала нам надо написать WCF RESTful [EN] сервис. Для начала определим дата-контракт:
Message.cs

using System.Runtime.Serialization;

namespace TestService
{
	[DataContract]
	public class Message
	{
		[DataMember(Order = 1)]
		public string Header { get; set; }

		[DataMember(Order =2)]
		public string Body { get; set; }
	}
}

Задаем порядок элементов, которые будет возвращать веб-сервис посредством Order = x.
Потом определим сервис-контракт:
ITestService.cs

using System.ServiceModel;
using System.ServiceModel.Web;

namespace TestService
{
	[ServiceContract]
	public interface ITestService
	{
		[OperationContract]
		[WebGet(UriTemplate = "/GetMessage/?header={header}&?body={body}", ResponseFormat = WebMessageFormat.Json)]
		Message ComposeMessage(string header, string body);
	}
}

Подробнее о UriTemplate можете почитать тут.
Реализуем сервис:
TestService.svc.cs

using System.ServiceModel.Activation;

namespace TestService
{
	public class TestService : ITestService
	{
		#region ITestService Members

		public Message ComposeMessage(string header, string body)
		{
			Message message = new Message() { Header = header, Body = body };

			return message;
		}

		#endregion
	}
}

И конечно же конфигурация сервиса:
web.config

<?xml version="1.0"?>
<configuration>
	<system.web>
		<compilation debug="true" targetFramework="4.0" />
	</system.web>
	<system.serviceModel>
		<services>
			<service name="TestService.TestService">
				<endpoint binding="webHttpBinding" contract="TestService.ITestService" behaviorConfiguration="webHttp"/>
			</service>
		</services>
		<behaviors>
			<endpointBehaviors>
				<behavior name="webHttp">
					<webHttp helpEnabled="true"/>
				</behavior>
			</endpointBehaviors>
			<serviceBehaviors>
				<behavior>
					<serviceMetadata httpGetEnabled="true"/>
				</behavior>
			</serviceBehaviors>
		</behaviors>
	</system.serviceModel>
	<system.webServer>
		<modules runAllManagedModulesForAllRequests="true"/>
	</system.webServer>
</configuration>

Размещать сервис мы будем в IIS(это можно сделать либо в Visual Studio либо через Диспетчер служб IIS). Создадим виртуальный каталог, назовем его TestService.
В случае размещения внутри служб IIS, управляемого WCF, среде WCF обычно требуется файл .svc, указывающий на тип службы, а также записи в файле web.config, информирующие WCF о конечной точке (привязке и поведениях среди прочих параметров настройки).

И последний штрих:
TestService.svc

<%@ ServiceHost Language="C#" Debug="true" Service="TestService.TestService" CodeBehind="TestService.svc.cs" %>

После всех действий наш виртуальный каталог должен иметь примерно следующее содержимое:

В bin фолдере должна лежать *.dll с сервисом.
Все наш сервис готов. Для того чтобы протестировать полученный результат, в адресной строке браузера наберем
localhost/TestService/TestService.svc/GetMessage/?header=Hello&?body=World
Результат должен выглядеть так:
{«Header»:«Hello»,«Body»:«World»}
Это и есть JSON Response.
Перейдем наконец-то к нашему Android приложению.
Советую перечитать этот пост. Из него позаимствуем реализацию AsyncTask.
Публикация всего кода не имеет смысла, поэтому «вырежем» от туда только метод который и будет разбирать JSON ответ, пришедший от сервиса. Вот его код:
private String getMessage(String header, String body) {
		HttpClient httpclient = new DefaultHttpClient();
		HttpGet httpget = new HttpGet(_resources.getString(R.string.serviceAddress) + "/GetMessage/?header="+ header + "&?body=" + body);

		HttpResponse response;
		try {
			response = httpclient.execute(httpget);

			HttpEntity entity = response.getEntity();

			if (entity != null) {
				InputStream instream = entity.getContent();
				String result = convertStreamToString(instream);
				JSONObject json = new JSONObject(result);

				// Parsing
				JSONArray nameArray = json.names();
				JSONArray valArray = json.toJSONArray(nameArray);

				_getResponse = nameArray.getString(0) + "="
						+ valArray.getString(0) + ", " + nameArray.getString(1)
						+ "=" + valArray.getString(1);

				instream.close();
			}

		} catch (Exception e) {
			_getResponse = e.getMessage();
		}

		return _getResponse;
	}

Адрес сервиса _serviceAddress будет иметь вид:
10.0.2.2/TestService/TestService.svc
поскольку, при обращении к localhost, мы получим Connection Refused IOException(кому интересно, подробнее читаем тут).
Также в файл AndroidManifest.xml надо добавить uses-permission для того чтобы приложение могло вызвать веб-сервис:
<uses-permission android:name="android.permission.INTERNET" />

Вот в принципе и все что я хотел рассказать…

Исходники:
Лежат тут.

Полезные ссылки:
Всем спасибо за внимание!
Tags: restful .netcsharpandroidwcfjsonksoap
Hubs: Development for Android
Total votes 33: ↑25 and ↓8 +17
Comments 13
Comments Comments 13

Popular right now