C#(Mono)开发手机及平板应用入门篇(含WCF服务实现)

来源:互联网 发布:java编码 编辑:程序博客网 时间:2024/05/08 19:42

摘要:本文是在开发Mono手机平板项目时,对安装Mono for Android工具,调用WCF服务,等一些要注意的问题进行汇总;其中包括WCF异步调用,SOAP代理类调用等。

一:前提:

1> MonoTouch 项目是实现c#跨平台开发iphone,ipad, android手机及平台应用利器;大家可以到官网:http://xamarin.com/monotouch 查看更多资料;

2> MonoTouch 开发WCF应用的文档可以参考:http://docs.xamarin.com/ios/tutorials/introduction_to_web_services

二:标准WCF应用的服务端和客户端web.config配置:

WCF4.0项目默认没有显示生成服务端web.config的xml,为了快速项目在测试环境和生产环境的部署,特别贴出服务端和客户端的xml配置,便于检查,全部的配置文件见文章结尾附注部分。

三:mono for andorid应用的开发

1> 安装开发工具,下载链接:http://xamarin.com/monotouch

2> VS2010 SP1 安装完成后,再安装SilverLight5版本,上文中SLSvcUtil.exe文件也是5.0版本,其它版本有问题。

3> SLSvcUtil.exe 生成代理类

cd C:\Program Files (x86)\Microsoft SDKs\Silverlight\v3.0\Tools
SlSvcUtil.exe http://localhost:49514/Service1.svc /directory:"c:\Users\abhatia\Desktop"
注:原英文dirctory中缺失 "/",此处修改。

4> 调试及运行

4.1>选择调试模拟器,并开始Start 模拟器:


4.2> 在模拟器开始运行后,一定要再次返回在下图界面中,点OK按钮一下,这样程序就可以到Android环境打开你要调试的代码示例了。


4.3> 注意第一次运行时比较慢,会拷贝一些运行时,内核框架到模拟器上,所以要耐心等待。如下图中左下角,用红笔标注的部分表示调试过程中的信息。


4.4> 默认项目依然是HelloWorld的应用,在模拟器上调试通程序后,大家可以构建自己的MonoTouch应用。




四:WCF服务调用示例

1. WCF异步调用

异步调用时采用了ManualResetEvent ,带调用操作后,对ManualResetEvent 执行WaitOne操作,在调用操作完成后,对ManualResetEvent 进行Set操作。

 public class WcfSample
    {
        private string s;
        ManualResetEvent mre = new ManualResetEvent(false);
        public string GetWcfData()
        {
            try
            {
                BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.None);
                var timeout = new TimeSpan(0, 1, 0);
                binding.SendTimeout = timeout;
                binding.OpenTimeout = timeout;
                binding.ReceiveTimeout = timeout;


                Service1Client client = new Service1Client(binding,
                    new EndpointAddress("http://192.168.0.16/MyErpWcf/Service1.svc"));
                client.GetDataCompleted += new EventHandler<GetDataCompletedEventArgs>(client_GetDataCompleted);
                client.GetDataAsync(8888);
                mre.WaitOne();
            }
            catch
            {
                throw;
            }


            return s;
        }

        private void client_GetDataCompleted(object sender, GetDataCompletedEventArgs e)
        {
            if (e.Error ==null)
            {
                s = e.Result;
                mre.Set();
            }
        }
    }

   将Wcf服务的返回数据处理:

  string s = (new WcfSample()).GetWcfData();

 备注:在调试时,wcf服务地址要用IP地址方式,则程序正常运行。如果直接用localhost,则出现EndpointNotFound异常。即使在hosts文件中添加解析记录也不起作用

2. SOAP消息格式调用

先用svcutil.exe生成代理类,然后将代理类添加到mono项目中,再引用代理类,从而实现调用WCF服务。

C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\SvcUtil.exe http://192.168.0.16/MyErpWcf/Service1.svc?wsdl

public class SoapSample
    {
        public string GetWcfData()
        {
            BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.None);
            var timeout = new TimeSpan(0, 1, 0);
            binding.SendTimeout = timeout;
            binding.OpenTimeout = timeout;
            binding.ReceiveTimeout = timeout;

            IService1 service = ChannelFactory<IService1>.CreateChannel(binding,
                new EndpointAddress("http://192.168.0.16/MyErpWcf/Service1.svc"));
            return service.GetData(8888);
        }
    }

   将Wcf服务的返回数据处理:

  string s = (new SoapSample()).GetWcfData();

五:其它更多示例

Mono for Android Sample:

https://github.com/xamarin/monodroid-samples

这些示例可以直接调试运行,非常方便,适合下载学习。


总结:

1. C# 跨平台的优势从MonoTouch项目一览无遗,对于没有时间和精力学习object c 和java的.net程序员来说,是一种最优选择;对于多平台的实现,可以借助WCF服务思想,而不是把业务逻辑暴露到各个UI展现层。此处可以多看SOA开发思想来设计分布式应用架构。

2. 文中示例代码都是调试后能够正常运行的示例,请大家做以参考。


附注:

1. WCF服务端web.config文件配置

1> bingdings节点

2> services节点

3> behaviors节点

注意:service节点配置时候,name和contract的名称不能重复,否则依然会报下面的异常,此时跟serviceMetadata 节点配置无关:

Metadata publishing for this service is currently disabled (WCF4) 

<system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="Basic" />
      </basicHttpBinding>
    </bindings>
    <services>
      <service name="MyErpWcf.Service1" behaviorConfiguration="ErpServiceBehavior">
        <endpoint address="" binding="basicHttpBinding" bindingName="Basic" contract="MyErpWcf.IService1">
          
          <identity>
            <dns value="localhost"/>
          </identity>
          
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ErpServiceBehavior">
          <!-- 为避免泄漏元数据信息,请在部署前将以下值设置为 false 并删除上面的元数据终结点 -->
          <serviceMetadata httpGetEnabled="true" policyVersion="Policy12" />
          <!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息 -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>


2. 客户端web.config配置:

1>. bingdings节点

2>. client 节点

<system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="Basic_IService1" closeTimeout="00:01:00" openTimeout="00:01:00"
                    receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
                    bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                    useDefaultWebProxy="true">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <security mode="None">
                        <transport clientCredentialType="None" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="UserName" algorithmSuite="Default" />
                    </security>
                </binding>
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost/MyErpWcf/Service1.svc" binding="basicHttpBinding"
                bindingConfiguration="Basic_IService1" contract="ServiceReference1.IService1"
                name="Basic_IService1" />
        </client>
    </system.serviceModel>



原创粉丝点击