public override void CreateLayerAsync(Resource layerResource, SpatialReference mapSpatialReference, object userState) { if (layerResource.ResourceType == ResourceType.DatabaseTable) { featureService = new FeatureService(layerResource.Url); featureService.GetFeatureServiceDetailsFailed += (o, e) => { OnCreateLayerFailed(e); }; featureService.GetFeatureServiceDetailsCompleted += (o, e) => { if (e.FeatureServiceInfo == null) { OnCreateLayerFailed(new ESRI.ArcGIS.Mapping.Core.ExceptionEventArgs(new Exception(Resources.Strings.ExceptionUnableToRetrieveLayerDetails), e.UserState)); return; } GeometryType GeometryType = GeometryType.Unknown; switch (e.FeatureServiceInfo.GeometryType) { case "esriGeometryPoint": GeometryType = GeometryType.Point; break; case "esriGeometryMultipoint": GeometryType = GeometryType.MultiPoint; break; case "esriGeometryPolyline": GeometryType = GeometryType.Polyline; break; case "esriGeometryPolygon": GeometryType = GeometryType.Polygon; break; } FeatureLayer newFeatureLayer = new FeatureLayer() { Url = featureService.Uri, ID = Guid.NewGuid().ToString("N"), Mode = FeatureLayer.QueryMode.OnDemand, Renderer = new ESRI.ArcGIS.Mapping.Core.Symbols.HiddenRenderer() }; newFeatureLayer.SetValue(MapApplication.LayerNameProperty, layerResource.DisplayName); newFeatureLayer.SetValue(Core.LayerExtensions.GeometryTypeProperty, GeometryType); newFeatureLayer.SetValue(Core.LayerExtensions.DisplayUrlProperty, layerResource.Url); if (e.FeatureServiceInfo.Fields != null) { Collection<FieldInfo> fields = new Collection<FieldInfo>(); foreach (Field field in e.FeatureServiceInfo.Fields) { if (field.DataType == "Microsoft.SqlServer.Types.SqlGeometry" || field.DataType == "esriFieldTypeGeometry") continue; fields.Add(new FieldInfo() { DisplayName = field.Name, FieldType = mapFieldType(field.DataType), Name = field.Name, VisibleInAttributeDisplay = true, VisibleOnMapTip = true, }); } newFeatureLayer.SetValue(Core.LayerExtensions.FieldsProperty, fields); } newFeatureLayer.OutFields.Add("*"); // Get all fields at configuration time OnCreateLayerCompleted(new CreateLayerCompletedEventArgs() { Layer = newFeatureLayer, UserState = e.UserState, GeometryType = GeometryType }); }; featureService.GetFeatureServiceDetails(userState); } else { OnCreateLayerFailed(new ESRI.ArcGIS.Mapping.Core.ExceptionEventArgs(new Exception(string.Format(Resources.Strings.ExceptionCannotCreateLayerForResourceType, layerResource.ResourceType.ToString())), userState)); } }
private void processResult(ArcGISWebClient.DownloadStringCompletedEventArgs e) { if (e.Cancelled) return; if (e.Error != null) { OnGetGroupLayerDetailsFailed(new ExceptionEventArgs(e.Error, e.UserState)); return; } if (string.IsNullOrEmpty(e.Result)) { OnGetGroupLayerDetailsFailed(new ExceptionEventArgs(new Exception(Resources.Strings.ExceptionEmptyResponse), e.UserState)); return; } LayerDetails layerDetails; try { string json = e.Result; Exception exception = Utils.CheckJsonForException(json); if (exception != null) { OnGetGroupLayerDetailsFailed(new ExceptionEventArgs(exception, e.UserState)); return; } byte[] bytes = Encoding.Unicode.GetBytes(json); using (System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(bytes)) { DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(typeof(LayerDetails)); layerDetails = dataContractJsonSerializer.ReadObject(memoryStream) as LayerDetails; memoryStream.Close(); } if (layerDetails == null) { OnGetGroupLayerDetailsFailed(new ExceptionEventArgs(new Exception(Resources.Strings.ExceptionUnableToDeserializeResponse), e.UserState)); return; } } catch (Exception ex) { OnGetGroupLayerDetailsFailed(new ExceptionEventArgs(ex, e.UserState)); return; } List<Resource> childResources = new List<Resource>(); if (layerDetails.SubLayers != null) { int totalSubLayerCount = layerDetails.SubLayers.Count; int subLayerCount = 0; string parentMapServerUrl = Uri.Substring(0, Uri.IndexOf("MapServer", StringComparison.OrdinalIgnoreCase)+9); foreach (SubLayer subLayer in layerDetails.SubLayers) { // In order to determine whether a sub layer is a group layer or not, we need to make more requests string subLayerUrl = string.Format("{0}/{1}", parentMapServerUrl, subLayer.ID); Layer lyr = new Layer(subLayerUrl, ProxyUrl); lyr.GetLayerDetailsFailed += (o, args) =>{ // Remove layer childResources.Remove(args.UserState as Resource); subLayerCount++; if(subLayerCount >= totalSubLayerCount) OnGetGroupLayerDetailsCompleted(new GetLayerDetailsCompletedEventArgs() { ChildResources = childResources, LayerDetails = layerDetails, UserState = e.UserState }); }; lyr.GetLayerDetailsCompleted += (o,args) =>{ subLayerCount++; if (args.LayerDetails == null) { childResources.Remove(args.UserState as Resource); return; } Resource childResource = args.UserState as Resource; childResource.ResourceType = args.LayerDetails.Type == "Group Layer" ? ResourceType.GroupLayer : ResourceType.Layer; childResource.DisplayName = args.LayerDetails.Name; childResource.Url = string.Format("{0}/{1}", parentMapServerUrl, args.LayerDetails.ID); childResource.ProxyUrl = ProxyUrl; childResource.Tag = args.LayerDetails.ID; if(subLayerCount >= totalSubLayerCount) OnGetGroupLayerDetailsCompleted(new GetLayerDetailsCompletedEventArgs() { ChildResources = childResources, LayerDetails = layerDetails, UserState = e.UserState }); }; // Add layer before validating to preserve catalog order. Layer will be removed if validation // fails. Resource child = new Resource(); childResources.Add(child); lyr.GetLayerDetails(child); } } else { OnGetGroupLayerDetailsCompleted(new GetLayerDetailsCompletedEventArgs() { ChildResources = childResources, LayerDetails = layerDetails, UserState = e.UserState }); } }
public override bool IsResourceSelectable(Resource resource, Filter filter) { return resource.ResourceType == ResourceType.DatabaseTable; }
public override bool SupportsChildResources(Resource resource, Filter filter) { bool hasChildResource = resource.ResourceType == ResourceType.Server || resource.ResourceType == ResourceType.Database; return hasChildResource; }
private void getChildResourcesForServer(Resource parentResource, Filter filter, object userState) { server = new Server(parentResource.Url) { FilterForSpatialContent = (filter & Filter.SpatiallyEnabledResources) == Filter.SpatiallyEnabledResources }; server.GetCatalogFailed += (o, e) => { OnGetChildResourcesFailed(e); }; server.GetCatalogCompleted += (o, e) => { OnGetChildResourcesCompleted(new GetChildResourcesCompletedEventArgs() { ChildResources = e.ChildResources, UserState = e.UserState }); }; server.GetCatalog(userState); }
public override Resource GetResource(string connectionString, string proxyUrl) { if (!connectionString.StartsWith("http://") && !connectionString.StartsWith("https://")) connectionString = string.Format("http://{0}", connectionString); // Initialize to "Server" so that "catalog" will be called with this value unless this logic detects that the // connection string actually refers to another type of resource like a map service, layer, etc. Resource res = new Resource() { Url = connectionString, ResourceType = ResourceType.Server, }; try { Uri myUri = new Uri(connectionString); if (myUri.IsAbsoluteUri) { string path = myUri.AbsolutePath; string[] pathComponents = path.Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries); if (pathComponents.Length >= 2) { // This is for SDS 10.1 which mimics ArcGIS Server if (String.Compare(pathComponents[pathComponents.Length - 1], "featureserver", StringComparison.CurrentCultureIgnoreCase) == 0) { res.ResourceType = ResourceType.FeatureServer; res.DisplayName = pathComponents[pathComponents.Length - 2]; return res; } else if (String.Compare(pathComponents[pathComponents.Length - 2], "databases", StringComparison.CurrentCultureIgnoreCase) == 0) { res.ResourceType = ResourceType.Database; res.DisplayName = pathComponents[pathComponents.Length - 1]; return res; } } if (pathComponents.Length >= 3) { if (String.Compare(pathComponents[pathComponents.Length - 2], "featureserver", StringComparison.CurrentCultureIgnoreCase) == 0) { // It may seem wrong to call this a GP Server when the URL is clearly indicating a child tool, but // we need to do this in order to get the parent service and all child tools since we want this // context in the tree control. res.ResourceType = ResourceType.FeatureServer; res.DisplayName = pathComponents[pathComponents.Length - 3]; // Store the layer "id" in the tag. This will be extracted and used when populating the tree // control in order to select the proper child item. res.Tag = pathComponents[pathComponents.Length - 1]; // Create a URL that removes the trailing layer id int i = res.Url.LastIndexOf("/"); if (i >= 0) res.Url = res.Url.Remove(i); return res; } else if (String.Compare(pathComponents[pathComponents.Length - 3], "databases", StringComparison.CurrentCultureIgnoreCase) == 0) { // We need to do this in order to get the parent database and all child tables since we want this // context in the tree control. res.ResourceType = ResourceType.Database; res.DisplayName = pathComponents[pathComponents.Length - 2]; // Store the layer "id" in the tag. This will be extracted and used when populating the tree // control in order to select the proper child item. res.Tag = pathComponents[pathComponents.Length - 1]; // Create a URL that removes the trailing layer id int i = res.Url.LastIndexOf("/"); if (i >= 0) res.Url = res.Url.Remove(i); return res; } } } } catch { } // Parse to determine if this return res; }
private void getFieldsInDatabaseTable(Resource parentResource, object userState) { featureServer = new FeatureService(parentResource.Url); featureServer.GetFeatureServiceDetailsFailed += (o, e) => { OnGetChildResourcesFailed(e); }; featureServer.GetFeatureServiceDetailsCompleted += (o, e) => { OnGetChildResourcesCompleted(new GetChildResourcesCompletedEventArgs() { ChildResources = e.ChildResources, UserState = e.UserState }); }; featureServer.GetFeatureServiceDetails(userState); }
private void getTablesInDatabase(Resource parentResource, object userState) { database = new Database(parentResource.Url); database.GetTablesInDatabaseFailed += (o, e) => { OnGetChildResourcesFailed(e); }; database.GetTablesInDatabaseCompleted += (o, e) => { OnGetChildResourcesCompleted(new GetChildResourcesCompletedEventArgs() { ChildResources = e.ChildResources, UserState = e.UserState }); }; database.GetTables(userState); }
public override void GetChildResourcesAsync(Resource parentResource, Filter filter, object userState) { if ((filter & Filter.None) == Filter.None || (filter & Filter.SpatiallyEnabledResources) == Filter.SpatiallyEnabledResources || (filter & Filter.FeatureServices) == Filter.FeatureServices) { switch (parentResource.ResourceType) { case ResourceType.Server: case ResourceType.FeatureServer: getChildResourcesForServer(parentResource, filter, userState); break; case ResourceType.Database: getTablesInDatabase(parentResource, userState); break; case ResourceType.DatabaseTable: getFieldsInDatabaseTable(parentResource, userState); break; } } else { OnGetChildResourcesCompleted(new GetChildResourcesCompletedEventArgs() { ChildResources = null, UserState = userState }); } }
private void processResult(ArcGISWebClient.DownloadStringCompletedEventArgs e) { if (e.Cancelled) return; if (e.Error != null) { OnGetCatalogFailed(new ExceptionEventArgs(e.Error, e.UserState)); return; } if (string.IsNullOrEmpty(e.Result)) { OnGetCatalogFailed(new ExceptionEventArgs(new Exception(Resources.Strings.ExceptionEmptyResponse), e.UserState)); return; } string json = e.Result; Exception exception = Utils.CheckJsonForException(json); if (exception != null) { OnGetCatalogFailed(new ExceptionEventArgs(exception, e.UserState)); return; } Catalog catalog = null; try { byte[] bytes = Encoding.Unicode.GetBytes(json); using (System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(bytes)) { DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(typeof(Catalog)); catalog = dataContractJsonSerializer.ReadObject(memoryStream) as Catalog; memoryStream.Close(); } } catch(Exception ex) { OnGetCatalogFailed(new ExceptionEventArgs(ex, e.UserState)); return; } if (catalog == null) { OnGetCatalogFailed(new ExceptionEventArgs(new Exception(Resources.Strings.ExceptionUnableToDeserializeCatalog), e.UserState)); return; } if (catalog.Folders == null && catalog.Services == null) { OnGetCatalogFailed(new ExceptionEventArgs(new Exception(Resources.Strings.ExceptionNoServicesFoundOnServer), e.UserState)); return; } List<Resource> childResources = new List<Resource>(); List<Resource> resources = Utility.GetResources(catalog, Filter, Uri, ProxyUrl, lockObj); int childCount = 0; int totalChildCount = resources != null ? resources.Count : 0; // If the catalog has any folders, add them to the returned list first if (catalog.Folders != null) { totalChildCount += catalog.Folders.Count; foreach (string folderName in catalog.Folders) { Folder folder = new Folder(string.Format("{0}/{1}", Uri, folderName), ProxyUrl) { Filter = Filter, }; folder.GetServicesInFolderFailed += (o, args) => { // Remove the folder lock (lockObj) { childResources.Remove(args.UserState as Resource); } childCount++; if (childCount >= totalChildCount) OnGetCatalogCompleted(new GetCatalogCompletedEventArgs() { ChildResources = childResources, UserState = e.UserState }); }; folder.GetServicesInFolderCompleted += (o, args) => { int nestedChildTotalCount = args.ChildResources.Count(); if (nestedChildTotalCount == 0) { // Remove the folder lock (lockObj) { childResources.Remove(args.UserState as Resource); } } childCount++; if (childCount >= totalChildCount) OnGetCatalogCompleted(new GetCatalogCompletedEventArgs() { ChildResources = childResources, UserState = e.UserState }); }; // Add the folder before validation so that the catalog order is preserved. Folder will be // removed if found to be invalid. Resource folderResource = new Resource() { DisplayName = folderName, Url = string.Format("{0}/{1}", Uri, folderName), ProxyUrl = ProxyUrl, ResourceType = ResourceType.Folder, }; lock (lockObj) { childResources.Add(folderResource); } folder.GetServices(folderResource); } } // Remove any undesired services due to filtering foreach (Resource childRes in resources) { IService childService = ServiceFactory.CreateService(childRes.ResourceType, childRes.Url, childRes.ProxyUrl); if (childService != null) { // Determine if filtering requires detailed information about the server and only make async call to // obtain detailed info if true. if (childService.IsServiceInfoNeededToApplyThisFilter(Filter)) { childService.ServiceDetailsDownloadFailed += (o, args) => { // Remove resource lock (lockObj) { childResources.Remove(args.UserState as Resource); } childCount++; if (childCount >= totalChildCount) OnGetCatalogCompleted(new GetCatalogCompletedEventArgs() { ChildResources = childResources, UserState = e.UserState }); }; childService.ServiceDetailsDownloadCompleted += (o, args) => { IService service = o as IService; if (service == null || !service.IsFilteredIn(Filter)) // check if service is filtered { // Remove resource lock (lockObj) { childResources.Remove(args.UserState as Resource); } } childCount++; if (childCount >= totalChildCount) OnGetCatalogCompleted(new GetCatalogCompletedEventArgs() { ChildResources = childResources, UserState = e.UserState }); }; // Add the service before validation so that the catalog order is preserved. Service will be // removed if found to be invalid. Resource childResource = new Resource() { DisplayName = childRes.DisplayName, Url = childService.Uri, ProxyUrl = ProxyUrl, ResourceType = childService.Type }; lock (lockObj) { childResources.Add(childResource); } childService.GetServiceDetails(childResource); } else { // Apply filtering using basic information, not detailed information if (childService != null && childService.IsFilteredIn(Filter)) { lock (lockObj) { childResources.Add(new Resource() { DisplayName = childRes.DisplayName, Url = childService.Uri, ProxyUrl = ProxyUrl, ResourceType = childService.Type }); } } ++childCount; } } } if (childCount >= totalChildCount) OnGetCatalogCompleted(new GetCatalogCompletedEventArgs() { ChildResources = childResources, UserState = e.UserState }); }
private void DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) { if (e.Cancelled) return; if (e.Error != null) { bool redownloadAttempted = WebClientFactory.RedownloadAttempted.Contains(webClient); if (Utils.IsMessageLimitExceededException(e.Error) && !redownloadAttempted) { // Re-issue the request which should serve it out of cache // and helps us avoid the error which is caused by setting AllowReadStreamBuffering=false // which was used to workaround the problem of SL4 and gzipped content WebClientFactory.RedownloadStringAsync(webClient, finalUrl, e.UserState); } else { if (redownloadAttempted) WebClientFactory.RedownloadAttempted.Remove(webClient); OnGetCatalogFailed(new ExceptionEventArgs(e.Error, e.UserState)); } return; } if (string.IsNullOrEmpty(e.Result)) { OnGetCatalogFailed(new ExceptionEventArgs(new Exception(Resources.Strings.ExceptionEmptyResponse), e.UserState)); return; } string json = e.Result; Exception exception = Utils.CheckJsonForException(json); if (exception != null) { OnGetCatalogFailed(new ExceptionEventArgs(exception, e.UserState)); return; } DatabaseCatalog catalog = null; try { byte[] bytes = Encoding.Unicode.GetBytes(json); using (System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(bytes)) { DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(typeof(DatabaseCatalog)); catalog = dataContractJsonSerializer.ReadObject(memoryStream) as DatabaseCatalog; memoryStream.Close(); } } catch (Exception ex) { OnGetCatalogFailed(new ExceptionEventArgs(ex, e.UserState)); return; } if (catalog == null) { OnGetCatalogFailed(new ExceptionEventArgs(new Exception(Resources.Strings.ExceptionUnableToDeserializeCatalog), e.UserState)); return; } List<Resource> childResources = new List<Resource>(); int totalDatabasesCount = catalog.Databases == null ? 0 : catalog.Databases.Count; if (catalog.Databases != null) { int databaseCount = 0; foreach (string databaseName in catalog.Databases) { Resource databaseResource = new Resource() { DisplayName = databaseName, Url = string.Format("{0}/{1}", Uri, databaseName), ResourceType = ResourceType.Database, }; if (!FilterForSpatialContent) { childResources.Add(databaseResource); } else { Database db = new Database(databaseResource.Url) { FilterForSpatialContent = true }; db.GetTablesInDatabaseFailed += (o, args) => { // remove the database childResources.Remove(args.UserState as Resource); databaseCount++; if (databaseCount >= totalDatabasesCount) { // all done, raise the event OnGetCatalogFailed(args); } }; db.GetTablesInDatabaseCompleted += (o, args) => { databaseCount++; bool hasAtleastOneSpatialTable = args.ChildResources.Count() > 0; if (!hasAtleastOneSpatialTable) { // remove the database childResources.Remove(args.UserState as Resource); } if (databaseCount >= totalDatabasesCount) { // all done, raise the event OnGetCatalogRequestCompleted(new GetCatalogCompletedEventArgs() { ChildResources = childResources, UserState = e.UserState }); } }; // Add database prior to validation to preserve catalog order. Database will be removed // if validation fails. Resource child = new Resource() { DisplayName = databaseName, Url = string.Format("{0}/{1}", Uri, databaseName), ResourceType = ResourceType.Database, }; childResources.Add(child); db.GetTables(child); } } } if(!FilterForSpatialContent || totalDatabasesCount == 0) { OnGetCatalogRequestCompleted(new GetCatalogCompletedEventArgs() { ChildResources = childResources, UserState = e.UserState }); } }
private void DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) { if (e.Cancelled) return; if (e.Error != null) { bool redownloadAttempted = WebClientFactory.RedownloadAttempted.Contains(webClient); if (Utils.IsMessageLimitExceededException(e.Error) && !redownloadAttempted) { // Re-issue the request which should serve it out of cache // and helps us avoid the error which is caused by setting AllowReadStreamBuffering=false // which was used to workaround the problem of SL4 and gzipped content WebClientFactory.RedownloadStringAsync(webClient, finalUrl, e.UserState); } else { if (redownloadAttempted) WebClientFactory.RedownloadAttempted.Remove(webClient); OnGetTablesInDatabaseFailed(new ExceptionEventArgs(e.Error, e.UserState)); } return; } if (string.IsNullOrEmpty(e.Result)) { OnGetTablesInDatabaseFailed(new ExceptionEventArgs(new Exception("Empty response"), e.UserState)); return; } DatabaseTables databaseTables = null; try { string json = e.Result; if (Utils.IsSDSCatalogResponse(json)) { // We were expecting a response consisting of tables, instead we got a response of the catalog // this must be because we formed/guessed our URL wrong OnGetTablesInDatabaseFailed(new ExceptionEventArgs(new Exception("Invalid response recieved. Catalog response recieved when expecting database tables"), e.UserState)); return; } Exception exception = Utils.CheckJsonForException(json); if (exception != null) { OnGetTablesInDatabaseFailed(new ExceptionEventArgs(exception, e.UserState)); return; } byte[] bytes = Encoding.Unicode.GetBytes(json); using (MemoryStream memoryStream = new MemoryStream(bytes)) { DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(typeof(DatabaseTables)); databaseTables = dataContractJsonSerializer.ReadObject(memoryStream) as DatabaseTables; memoryStream.Close(); } if (databaseTables == null) { OnGetTablesInDatabaseFailed(new ExceptionEventArgs(new Exception("Unable to deserialize response"), e.UserState)); return; } List<Resource> childResources = new List<Resource>(); int totalTableCount = databaseTables.Tables != null ? databaseTables.Tables.Count : 0; if (databaseTables.Tables != null) { int tableCount = 0; foreach (string table in databaseTables.Tables) { Resource databaseTable = new Resource() { ResourceType = ResourceType.DatabaseTable, DisplayName = table, Url = string.Format("{0}/{1}", Uri, table), }; if (FilterForSpatialContent) { FeatureService featureService = new FeatureService(databaseTable.Url); featureService.GetFeatureServiceDetailsFailed += (o, args) => { // Remove the table childResources.Remove(args.UserState as Resource); tableCount++; if (tableCount >= totalTableCount) { // all done raise the event OnGetTablesInDatabaseFailed(args); } }; featureService.GetFeatureServiceDetailsCompleted += (o, args) => { tableCount++; if (args.FeatureServiceInfo == null || !args.FeatureServiceInfo.DoesTableHasGeometryColumn()) { // Remove the table childResources.Remove(args.UserState as Resource); } if (tableCount >= totalTableCount) { // all done raise the event OnGetTablesInDatabaseCompleted(new GetTablesInDatabaseCompletedEventArgs() { ChildResources = childResources, UserState = e.UserState }); } }; // Add table before validation to preserve catalog order. Table will be removed if // validation fails. Resource child = new Resource() { ResourceType = ResourceType.DatabaseTable, DisplayName = databaseTable.DisplayName, Url = databaseTable.Url, }; childResources.Add(child); featureService.GetFeatureServiceDetails(child); } else { childResources.Add(databaseTable); } } } if (!FilterForSpatialContent || totalTableCount == 0) { OnGetTablesInDatabaseCompleted(new GetTablesInDatabaseCompletedEventArgs() { ChildResources = childResources, UserState = e.UserState }); } } catch (Exception ex) { OnGetTablesInDatabaseFailed(new ExceptionEventArgs(ex, e.UserState)); } }
private void processResult(ArcGISWebClient.DownloadStringCompletedEventArgs e) { if (e.Cancelled) return; if (e.Error != null) { OnGetServicesInFolderFailed(new ExceptionEventArgs(e.Error, e.UserState)); return; } if (string.IsNullOrEmpty(e.Result)) { OnGetServicesInFolderFailed(new ExceptionEventArgs(new Exception(Resources.Strings.ExceptionEmptyResponse), e.UserState)); return; } Catalog catalog = null; try { string json = e.Result; byte[] bytes = Encoding.Unicode.GetBytes(json); using (System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(bytes)) { DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(typeof(Catalog)); catalog = dataContractJsonSerializer.ReadObject(memoryStream) as Catalog; memoryStream.Close(); } if (catalog == null) { OnGetServicesInFolderFailed(new ExceptionEventArgs(new Exception(Resources.Strings.ExceptionUnableToDeserializeResponse), e.UserState)); return; } bool retrieveChildServices = (Filter & Filter.CachedResources) == Filter.CachedResources; List<Resource> resources = Utility.GetResources(catalog, Filter, Uri, ProxyUrl); if (retrieveChildServices && resources.Count > 0) { int childCount = 0; List<Resource> childResources = new List<Resource>(); foreach (Resource childResource in resources) { IService service = ServiceFactory.CreateService(childResource.ResourceType, childResource.Url, childResource.ProxyUrl); if (service != null) { service.ServiceDetailsDownloadFailed += (o, args) => { // Remove service childResources.Remove(args.UserState as Resource); childCount++; if (childCount >= resources.Count) OnGetServicesInFolderCompleted(new GetServicesInFolderCompletedEventArgs() { ChildResources = childResources, UserState = e.UserState }); }; service.ServiceDetailsDownloadCompleted += (o, args) => { childCount++; IService ser = o as IService; if (ser == null || !ser.IsFilteredIn(Filter)) { // Remove service childResources.Remove(args.UserState as Resource); } if (childCount >= resources.Count) OnGetServicesInFolderCompleted(new GetServicesInFolderCompletedEventArgs() { ChildResources = childResources, UserState = e.UserState }); }; // Add the service before validation so that the catalog order is preserved. Service will be // removed if found to be invalid. Resource child = new Resource() { DisplayName = childResource.DisplayName, Url = service.Uri, ProxyUrl = ProxyUrl, ResourceType = service.Type, }; childResources.Add(child); service.GetServiceDetails(child); } } } else { OnGetServicesInFolderCompleted(new GetServicesInFolderCompletedEventArgs() { ChildResources = resources, UserState = e.UserState }); } } catch(Exception ex) { OnGetServicesInFolderFailed(new ExceptionEventArgs(ex, e.UserState)); } }