如何在ArcGIS Viewer for Silverlight中使用WCF服务完成降雨量专题图显示(二)
2013-08-31 15:42
483 查看
上一节我们建立了一个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的图标显示如下图:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/01/8c7ce36bae14c746be80d828a5bec6ef)
现在进入重头戏,建立并调用WCF。
首先在解决方案中新建一个WCF服务应用程序,如图:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/01/87a142a4758914eb8865efcf62499531)
在本例中我就不实现对数据库的调用啥的了,直接在服务中返回个double的列表,用来当作雨量数据。
现在按照大家的理解,应该是在建立的WCFSilverlight工程中添加Service的服务引用了吧?
先这样尝试下:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/01/9d871451a07060b7060e790148c27a80)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/01/417733720be5bf1e1208a18e67ff5aea)
添加之后在QueryToolWindow中添加引用using WCFSilverlight.ServiceReference
在QueryToolWindow中添加个按钮来调用下服务,看是否可以使用。
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/01/6bd4e545c8ceb22ba7e13a954b5e2c6e)
运行一下,点击Button之后就会出现这个错误:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/01/e1ea87cec0aff0b9346ff357572792a2)
“在 .xap 应用程序包中无法找到“ServiceReferences.ClientConfig”。”????!!
开什么玩笑,它不是明明白白的在我的工程里面吗?
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/01/929a7b886f2b76e68031cb4804cf1508)
这就是我想给大家分享这篇博客的最主要原因了。我当初碰到这个问题的时候甚至把.xap用zip解出来看到底放进去了没有,结果是有!
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/01/2b807a56d88bdd0b443071a5e2733913)
那么,问题就清楚了,包里面有东西但是没有应有的效果,这就证明是Viewer生成的站点不去解析这个文件!仔细想想,我突然恍然大悟:这个ClientConfig应该放在站点的根目录才能有配置作用啊,但是通过.xap打包了之后,显然宿主站点不认识这个文件了。
那么让我们看看这个配置文件配置了些什么吧。
我已经把他们各自配置的作用注释上去了,那么是不是意味着只要我用代码实现了这些配置,服务就能正常用了呢?
于是把上面的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());
}结果还是报错,不过好在错误已经不是原来那个了:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/01/539e02e17391cd4ab40bfb27b2be6de4)
如图,其实是在站点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>
再尝试一下:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/01/2593fcdf98b61223573caa7e655b4c76)
很好!查询的框弹出来了。
这样我们就完成了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服务的调用,下一节我和大家一起研究怎么把这些数据做成专题图,并且利用自定义的样式控制他们。
相关文章推荐
- 如何在ArcGIS Viewer for Silverlight中使用WCF服务完成降雨量专题图显示(一)
- ArcGIS API for Silverlight开发入门(8):在程序中使用Virtual Earth的服务
- 使用Visifire+ArcGIS API for Silverlight实现Graphic信息的动态图表显示
- 使用Visifire+ArcGIS API for Silverlight实现Graphic信息的动态图表显示
- Silverlight:如何在使用WCF的时候动态指定服务地址
- ArcGis For Silverlight API,地图显示Gis,绘制点,线,绘制图等(二)--Silverlight 配置动态的 webService、动态加载ArcGis地图服务
- arcgis for flex api version3.7 教程:3.如何使用QueryTask查询地图服务
- ArcGIS API for Silverlight开发入门(8):在程序中使用Virtual Earth的服务
- ArcGis For Silverlight API,地图显示Gis,绘制点,线,绘制图等(二)--Silverlight 配置动态的 webService、动态加载ArcGis地图服务
- ArcGis For Silverlight API,地图显示Gis,绘制点,线,绘制图等(二)--Silverlight 配置动态的 webService、动态加载ArcGis地图服务
- 使用Visifire+ArcGIS API for Silverlight实现Graphic信息的动态图表显示
- ArcGIS API for Silverlight 使用GP服务实现要素裁剪功能
- ArcGIS API for Silverlight 使用GP服务实现要素裁剪功能
- ArcGIS API for Silverlight开发入门(8):在程序中使用Virtual Earth的服务
- ArcGIS Viewer for Silverlight 系列:使用Application Builder快速构建GIS应用
- 使用Visifire+ArcGIS API for Silverlight实现Graphic信息的动态图表显示
- ArcGIS API for Silverlight 使用GP服务实现要素裁剪功能
- ArcGIS API for Silverlight开发入门(8):在程序中使用Virtual Earth的服务
- Silverlight:如何在使用WCF的时候动态指定服务地址
- ArcGIS API for Silverlight 使用GP服务实现要素裁剪功能