protected RequestBodyDispatchFormatter(OperationDescription operation, UriTemplate uriTemplate, QueryStringConverter converter, IDispatchMessageFormatter innerFormatter) { // The inner formatter is the default formatter that WCF normally uses. When the request can't be deserialized // by our custom formatter, we'll use the default formatter. this.innerFormatter = innerFormatter; // We'll use the query string converter for both Uri query string parameters and the values of the // form post data this.QueryStringConverter = converter; // Messages[0] is the request message MessagePartDescriptionCollection parts = operation.Messages[0].Body.Parts; // This partsCount includes the Uri parts (both path segment variables and query string variables) // 1 body content part partsCount = parts.Count; ReadOnlyCollection <string> uriPathVariables = uriTemplate.PathSegmentVariableNames; ReadOnlyCollection <string> uriQueryVariables = uriTemplate.QueryValueVariableNames; // For each part of the message, we need to capture it's name, type, and whether it is // a Uri path segment variable, a Uri query string variable or the body content operationParameterInfo = new OperationParameterInfo[partsCount]; for (int x = 0; x < partsCount; x++) { string name = parts[x].Name; Type type = parts[x].Type; // We'll assume this part is the message body, but then check if there are // uri variables that match the name OperationParameterKind kind = OperationParameterKind.MessageBody; bool canConvert = false; CaseInsensitiveEqualityComparer <string> comparer = new CaseInsensitiveEqualityComparer <string>(); if (uriPathVariables.Contains(name, comparer)) { kind = OperationParameterKind.UriPathVariable; } else if (uriQueryVariables.Contains(name, comparer)) { canConvert = converter.CanConvert(type); kind = OperationParameterKind.UriQueryVariable; } else { // If we reached here, then this part really is the message body part. // We'll store the name and type in the class properties so that derived // types have access to this information this.BodyParameterName = name; this.BodyParameterType = type; } operationParameterInfo[x] = new OperationParameterInfo(kind, type, name, canConvert); } }
/// <summary> /// For each service described in the data grid view, adds records to the metadata cache database to describe the service /// </summary> /// <param name="servicesToAdd">List of services to add to the metadata cache database</param> /// <param name="e">Parameters from the BackgroundWorker</param> /// <returns>Parameters (task type, output message, rows that were successfully added) to be processed by a BackgroundWorker event handler</returns> private object[] AddServicesToDatabase(List <DataServiceInfo> servicesToAdd, DoWorkEventArgs e) { // Build parameters to pass to the background worker object[] parameters = new object[3]; parameters[0] = BackgroundWorkerTasks.UpdateDatabase; parameters[1] = "Operation cancelled"; List <int> rowsToSelect = new List <int> (); bgwMain.ReportProgress(0, "Getting list of existing WaterOneFlow services from database..."); // Get a list of existing URLs from the metadata cache databsae List <string> existingUrls = DatabaseOperations.GetCacheServiceUrls(true); // Add service records to the database int totalSteps = servicesToAdd.Count; int currentStep = 0; int countAlreadyExists = 0; int countInvalidService = 0; IEqualityComparer <string> comparer = new CaseInsensitiveEqualityComparer(); MetadataCacheManagerSQL cacheManager = DatabaseOperations.GetCacheManager(); for (int i = 0; i < servicesToAdd.Count; i++) { if (bgwMain.CancellationPending) { e.Cancel = true; return(parameters); } currentStep++; bgwMain.ReportProgress(100 * currentStep / totalSteps, "Checking service " + currentStep + " of " + totalSteps + "..."); DataServiceInfo serviceInfo = servicesToAdd[i]; // Check if the service already exists in the database if (existingUrls.Contains(serviceInfo.EndpointURL, comparer) == true) { countAlreadyExists += 1; continue; } // Check that the URL is for a live service if (this.mnuCheckForValidService.Checked == true) { // Attempt to create a WaterOneFlowServiceClient from the URL. If the URL is not for a WaterOneFlow service, an error is thrown in the constructor. try { WaterOneFlowClient waterOneFlowClient = new WaterOneFlowClient(serviceInfo.EndpointURL); DataServiceInfo clientServiceInfo = waterOneFlowClient.ServiceInfo; serviceInfo.ServiceName = clientServiceInfo.ServiceName; serviceInfo.Protocol = clientServiceInfo.Protocol; serviceInfo.ServiceType = clientServiceInfo.ServiceType; serviceInfo.Version = clientServiceInfo.Version; } catch { countInvalidService += 1; continue; } } // Save the service cacheManager.SaveDataService(serviceInfo); existingUrls.Add(serviceInfo.EndpointURL); rowsToSelect.Add(i); } // Prepare a message to the user string message = ""; int serviceCount = rowsToSelect.Count; if (serviceCount == 0) { message += "No new services added to metadata cache database.\n\n "; } else if (serviceCount == 1) { message += "1 new service added to metadata cache database.\n\n"; } else { message += serviceCount.ToString() + " new services added to metadata cache database.\n\n"; } if (countAlreadyExists == 1) { message += "1 service was not added because it already exists in the database.\n\n"; } else if (countAlreadyExists > 1) { message += countAlreadyExists.ToString() + " services were not added because they already exist in the database.\n\n"; } if (countInvalidService == 1) { message += "1 service was not added because it does not point to a valid WaterOneFlow service.\n\n"; } else if (countInvalidService > 1) { message += countInvalidService.ToString() + " services were not added because they do not point to a valid WaterOneFlow service.\n\n"; } if (serviceCount == 1) { message += "Remember to download metadata for this service in the Metadata Fetcher window."; } else if (serviceCount > 1) { message += "Remember to download metadata for these services in the Metadata Fetcher window."; } parameters[1] = message; parameters[2] = rowsToSelect; return(parameters); }
/// <summary> /// Finds rows for services in the view for which a record already exists in the metadata cache database with the same URL /// </summary> /// <param name="rows">List of DataServiceInfo objects whose URLs we want to check (the service URL is assumed to have come from a row in an object such as a data grid view)</param> /// <param name="e">Parameters from the BackgroundWorker</param> /// <returns>Parameters (task type, output message, rows for which a record already exists in the metadata cache database with the same URL) to be processed by a BackgroundWorker event handler</returns> private object[] CheckForServicesInCache(List <DataServiceInfo> rows, DoWorkEventArgs e) { // Build parameters to pass to the background worker object[] parameters = new object[3]; parameters[0] = BackgroundWorkerTasks.CheckForExisingServices; parameters[1] = "Operation cancelled"; List <int> rowsToSelect = new List <int> (); // Get a list of existing URLs from the metadata cache databsae if (e != null) { bgwMain.ReportProgress(0, "Getting list of existing WaterOneFlow services from database..."); } List <string> existingUrls = DatabaseOperations.GetCacheServiceUrls(true); // Check all items in the view int totalSteps = rows.Count; int currentStep = 0; IEqualityComparer <string> comparer = new CaseInsensitiveEqualityComparer(); for (int i = 0, len = rows.Count; i < len; i++) { DataServiceInfo row = rows[i]; if (e != null) { if (bgwMain.CancellationPending) { e.Cancel = true; return(parameters); } currentStep++; bgwMain.ReportProgress(100 * currentStep / totalSteps, "Checking service " + currentStep + " of " + totalSteps + "..."); } string serviceUrl = row.EndpointURL; if (existingUrls.Contains(serviceUrl, comparer) == true) { rowsToSelect.Add(i); } } // Prepare a message to the user // TODO: This message should be created outside of this service, and instead should be done in the display logic string message = ""; int existingCount = rowsToSelect.Count; if (existingCount == 0) { message = "No services with the same URL were found in the metadata cache database"; } else if (existingCount == 1) { message = "1 service has a URL that already exists in the metadata cache database. This service has been selected."; } else { message = existingCount.ToString() + " services have URLs that already exist in the metadata cache database. These services have been selected."; } parameters[1] = message; parameters[2] = rowsToSelect; return(parameters); }