如何在ArcGIS Viewer for Silverlight中使用WCF服务完成降雨量专题图显示(二)

上一节我们建立了一个Viewer for Silverlight的空工具,并且让它能够在我们配置的Viewer框架中调用,接下来我们就讲述怎么在这个工具中调用WCF服务。

首先完善一下QueryToolWindow,让它能够查询发出的服务图层的数据,并能将数据在Viewer生成的应用程序中显示出来。

关键代码为:

public partial class QueryToolWindow : UserControl
    {
        QueryTool QueryTool = null;
        QueryTask QueryTask = null;

        GraphicsLayer RainPointLayer = null;

        public QueryToolWindow(QueryTool queryTool)
        {
            this.QueryTool = queryTool;
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(QueryToolWindow_Loaded);
        }

        void QueryToolWindow_Loaded(object sender, RoutedEventArgs e)
        {
            this.QueryTask = new QueryTask(this.QueryTool.LayersDic["Point"]);
            this.QueryTask.Failed += new EventHandler<TaskFailedEventArgs>(QueryTask_Failed);
            this.QueryTask.ExecuteCompleted += new EventHandler<QueryEventArgs>(QueryTask_ExecuteCompleted);
            Query query = new Query()
            {
                Where = "1=1",
                ReturnGeometry = true,
                OutFields = new OutFields() { "ID" },
                OutSpatialReference = MapApplication.Current.Map.SpatialReference
            };
            this.QueryTask.ExecuteAsync(query);
        }

        void QueryTask_ExecuteCompleted(object sender, QueryEventArgs e)
        {
            GraphicsLayer layer = new GraphicsLayer();
            layer.Renderer = new SimpleRenderer() { 
                Symbol = new SimpleMarkerSymbol(){ 
                    Color = new SolidColorBrush(Colors.Red),
                    Size = 10
                } };
            foreach (Graphic graphic in e.FeatureSet)
            {
                layer.Graphics.Add(graphic);
            }
            MapApplication.Current.Map.Layers.Add(layer);
        }

        void QueryTask_Failed(object sender, TaskFailedEventArgs e)
        {
            MessageBox.Show("查询失败!");
        }
}
}
点击QueryTool的图标显示如下图:

现在进入重头戏,建立并调用WCF。

首先在解决方案中新建一个WCF服务应用程序,如图:

在本例中我就不实现对数据库的调用啥的了,直接在服务中返回个double的列表,用来当作雨量数据。

public class Service : IService
    {
        public Dictionary<int,double> GetRainData(int value)
        {
            Dictionary<int, double> Result = new Dictionary<int, double>();
            Random TheRandom = new Random();

            for (int i = 0; i < value; i++)
            {
                Result.Add(i, TheRandom.NextDouble() * 100);
            }
            return Result;
        }
    }

现在按照大家的理解,应该是在建立的WCFSilverlight工程中添加Service的服务引用了吧?

先这样尝试下:


添加之后在QueryToolWindow中添加引用using WCFSilverlight.ServiceReference

在QueryToolWindow中添加个按钮来调用下服务,看是否可以使用。


运行一下,点击Button之后就会出现这个错误:



“在 .xap 应用程序包中无法找到“ServiceReferences.ClientConfig”。”????!!

开什么玩笑,它不是明明白白的在我的工程里面吗?



这就是我想给大家分享这篇博客的最主要原因了。我当初碰到这个问题的时候甚至把.xap用zip解出来看到底放进去了没有,结果是有!


那么,问题就清楚了,包里面有东西但是没有应有的效果,这就证明是Viewer生成的站点不去解析这个文件!仔细想想,我突然恍然大悟:这个ClientConfig应该放在站点的根目录才能有配置作用啊,但是通过.xap打包了之后,显然宿主站点不认识这个文件了。

那么让我们看看这个配置文件配置了些什么吧。

<configuration>
    <system.serviceModel>
        <bindings>
            <!-- 绑定方式 -->
            <basicHttpBinding>
                <binding name="BasicHttpBinding_IService" maxBufferSize="2147483647"
                    maxReceivedMessageSize="2147483647">
                    <security mode="None" />
                </binding>
            </basicHttpBinding>
        </bindings>
        <client>
            <!-- 客户端终结点 -->
            <endpoint address="http://localhost:50572/Service.svc" binding="basicHttpBinding"
                bindingConfiguration="BasicHttpBinding_IService" contract="ServiceReference.IService"
                name="BasicHttpBinding_IService" />
        </client>
    </system.serviceModel>
</configuration>

我已经把他们各自配置的作用注释上去了,那么是不是意味着只要我用代码实现了这些配置,服务就能正常用了呢?

于是把上面的Button事件改成这样:

private void Button_Click(object sender, RoutedEventArgs e)
        {
            //定义绑定
            Binding bingding = new BasicHttpBinding(BasicHttpSecurityMode.None) { MaxReceivedMessageSize = int.MaxValue, MaxBufferSize = int.MaxValue };
            //定义终结点
            EndpointAddress address = new EndpointAddress("http://localhost:9015/Service.svc");

            ServiceClient Client = new ServiceClient(bingding, address);
            Client.GetRainDataCompleted += new EventHandler<GetRainDataCompletedEventArgs>(Client_GetRainDataCompleted);

            Client.GetRainDataAsync(200);
        }

        void Client_GetRainDataCompleted(object sender, GetRainDataCompletedEventArgs e)
        {
            MessageBox.Show(e.Result.Count.ToString());
        }
结果还是报错,不过好在错误已经不是原来那个了:


如图,其实是在站点http://localhost:50572下面没有合适的跨域策略文件。

这里注意,需要在ClientAccessPolicy.xml允许http-request-headers:

<?xml version="1.0" encoding="utf-8" ?>   
<access-policy>   
<cross-domain-access>   
<policy>   
<allow-from http-request-headers="*">   
<domain uri="*"/>   
</allow-from>   
<grant-to>   
<resource path="/" include-subpaths="true"/>   
</grant-to>   
</policy>   
</cross-domain-access>   
</access-policy>
再尝试一下:


很好!查询的框弹出来了。

这样我们就完成了WCF服务的调用,下一节我和大家一起研究怎么把这些数据做成专题图,并且利用自定义的样式控制他们。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值