App Inventor 使用 TinyWebDb 接口与 WCF 服务通信





5.00/5 (5投票s)
在 WCF 服务上实现 TinyWebDb 接口,
引言
MIT App Inventor (前身为 Google App Inventor) 是一个用于开发 Android 应用程序的 RAD (快速应用程序开发) 工具。它拥有许多有用的功能,但对 Web 服务通信的支持非常有限。
使用 App Inventor 开发的 Android 应用程序只能通过 TinyWebDb 接口与 Web 服务通信。基本上,TinyWebDb 是一个简单的基于 Web 的键值数据库接口,只有两个方法:StoreValue(tag, value)
和 GetValue(tag)
。
下面的文章介绍了使用 WCF 服务实现 TinyWebDb 接口,从而实现了 Android 应用程序与 .Net 代码之间的通信。
背景
WCF (Windows Communication Foundation) 是 Microsoft 在 .NET Framework 中用于构建互联的、面向服务的应用程序的技术。要了解使用 WCF 创建 Web 服务的入门知识,请参阅本文: 初学者教程:理解 Windows Communication Foundation (WCF)
App Inventor 是一个非常简单的基于 Web 的 Android 可视化编程工具,无需任何 Java 技能或 Android 应用程序生命周期知识。要了解 App Inventor 的入门知识,请参阅本文: Google App Inventor
TinyWebDb API
TinyWebDb 是一个 RESTful 接口,这意味着它使用基本的 HTTP 请求,如 GET 或 POST (而不是更复杂的协议,如 SOAP 或 CORBA,这些协议使用特定于协议的请求格式)。
TinyWebDb 接口中有两个方法:StoreValue 和 GetValue。
StoreValue 使用 HTTP POST 请求调用,带有两个文本参数“tag”和“value”。
URL:{ServiceURL}/storeavalue
请求格式为 XML,内容类型为“application/x-www-form-urlencoded
”。这是 WCF 服务的默认值,因此不应在方法定义中特别说明。
响应格式为 JSON:["STORED", "{tag}", {value}]
,例如:["STORED", "testValue", "\"Hello World!\""]
GetValue 使用 HTTP POST 请求调用,带有一个文本参数“tag”。
URL:{ServiceURL}/getvalue
与 StoreValue 一样,请求格式为 XML,内容类型为默认值。
响应格式为 JSON:["VALUE","{tag}", {value}]
,例如:["VALUE", "testValue", "\"Hello World!\""]
在 WCF 服务中实现 TinyWebDb API
- 打开 VS 2010。选择新建项目,然后选择 WCF -> WCF 服务应用程序。
- 右键单击项目,选择“添加”->“新建项”->“WCF 服务”。将添加两个文件:接口 (以 I 开头,以 .cs 结尾,例如 IMyService.sc) 和服务 (以 .svc 结尾,例如 MyService.svc)。
- 打开接口文件。在这里,我们需要为 StoreValue 和 GetValue 方法定义操作契约。以下代码可以实现此功能:
[ServiceContract]
public interface IMyService
{
[OperationContract(Name = "getvalue")]
[WebInvoke(Method = "POST",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "getvalue")]
string[] getvalue(Stream data);
[OperationContract(Name = "storeavalue")]
[WebInvoke(Method = "POST",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "storeavalue")]
string[] storeavalue(Stream data);
}
在这里,我们显式指定了 HTTP 请求类型 (两种情况下都是 POST)、响应格式 (JSON) 和返回类型 (字符串数组,它将自动转换为 JSON 格式 ["string1", "string2", ...])。
- 打开服务文件,并实现上面描述的接口。为了简单起见,我硬编码了返回的值。在实际应用中,必须在这些过程内部实现一些有意义的业务逻辑。
public class MyService : IMyService
{
public string[] getvalue(Stream data)
{
StreamReader sr = new StreamReader(data);
string stringData = sr.ReadToEnd();
string tag = stringData.Substring(4);
string[] resultStringArray = new string[3];
resultStringArray[0] = "VALUE";
resultStringArray[1] = "testValue";
resultStringArray[2] = "Hello World!";
return resultStringArray;
}
public string[] storeavalue(Stream data)
{
StreamReader sr = new StreamReader(data);
string stringData = sr.ReadToEnd();
string tag = stringData.Substring(4, stringData.IndexOf("&value=") - 4);
string value = stringData.Substring(stringData.IndexOf("&value=") + 7);
string[] resultStringArray = new string[3];
resultStringArray[0] = "STORED";
resultStringArray[1] = "testValue";
resultStringArray[2] = "Hello World!";
return resultStringArray;
}
}
- 打开 Web.config 文件,并对 RESTful JSON 的工作进行一些必要的更改。这意味着我们需要定义
webHttpBinding
和mexHttpBinding
,并为服务定义httpGetEnabled
="true",为终结点定义webHttp
。
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="myServiceBehavior" >
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
<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>
<endpointBehaviors>
<behavior name="webHttp">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="WcfRestBased.MyService"
behaviorConfiguration="myServiceBehavior" >
<endpoint name="webHttpBinding"
address="" binding="webHttpBinding"
contract="WcfRestBased.IMyService"
behaviorConfiguration="webHttp"
>
</endpoint>
<endpoint name="mexHttpBinding"
address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"
/>
</service>
</services>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
为了指定正确的服务名称,右键单击服务并选择“查看标记”选项。
现在生成项目并将其部署到主机。如果您打算使用本地 Wi-Fi 访问 Web 服务器,可以使用本地 IIS 托管,如本文所述: 初学者教程:如何托管 WCF 服务 (IIS 托管和自托管)
从 App Inventor 应用程序访问 WCF 服务
- 前往 http://appinventor.mit.edu/,点击“创建”创建一个新项目。如果这是您第一次访问 App Inventor,系统会提示您注册。您将看到一个空项目,如下所示:
- 将两个标签和两个按钮拖到屏幕上。
- 在“调色板”中的“存储”类别下,将“TinyWebDb”组件拖到屏幕上。它将添加到“非可见组件”列表中。
- 在 TinyWebDb 组件的属性中,将 ServiceURL 更改为您新创建的服务地址,例如 http://192.168.1.38/MyService.svc。如果您不知道计算机的 IP 地址,请单击“开始”,在搜索框中键入“cmd”,然后键入“ipconfig”。
- 单击 App Inventor 编辑器右上角的“块”按钮。这将打开您的项目代码。从“块”类别拖动代码组件,直到您的应用程序看起来像这样:
现在您需要在真实的 Android 设备上测试您的应用程序。
- 首先,从 Google Play 商店在您的 Android 设备上安装应用程序“MIT AI2 Companion”。
- 接下来,在 App Inventor 的项目页面中,单击“连接”->“AI companion”。使用屏幕上显示的二维码或文本代码将您的 Android 设备连接到您的项目。
- 当您新创建的应用程序在 Android 设备上打开时,单击“存储值”和“获取值”按钮。您应该会看到应用程序收到了来自 Web 服务器的响应。
结论
这个简单的示例演示了如何将 Android 应用程序连接到 WCF 服务。连接后,我们可以实现任何我们想要的自定义逻辑:创建聊天、从数据库请求和发送值等等。有了这项技术,您就可以将 Android 设备变成您选择的几乎任何 .Net 应用程序的远程控制器。
致谢
以下文章和博客帖子提供了宝贵的见解:
开发 WCF RESTful 服务,