public static MessageFilterTable <IEnumerable <ServiceEndpoint> > CreateFilterTable(string name)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw FxTrace.Exception.ArgumentNullOrEmpty("name");
            }

            RoutingSection routingSection = (RoutingSection)ConfigurationManager.GetSection("system.serviceModel/routing");

            if (routingSection == null)
            {
                throw FxTrace.Exception.AsError(new InvalidOperationException(SR2.RoutingSectionNotFound));
            }

            FilterTableEntryCollection routingTableElement = routingSection.FilterTables[name];

            if (routingTableElement == null)
            {
                throw FxTrace.Exception.AsError(new InvalidOperationException(SR2.RoutingTableNotFound(name)));
            }
            XmlNamespaceManager xmlNamespaces = new XPathMessageContext();

            foreach (NamespaceElement nsElement in routingSection.NamespaceTable)
            {
                xmlNamespaces.AddNamespace(nsElement.Prefix, nsElement.Namespace);
            }

            FilterElementCollection filterElements = routingSection.Filters;
            MessageFilterTable <IEnumerable <ServiceEndpoint> > routingTable = new MessageFilterTable <IEnumerable <ServiceEndpoint> >();

            foreach (FilterTableEntryElement entry in routingTableElement)
            {
                FilterElement filterElement = filterElements[entry.FilterName];
                if (filterElement == null)
                {
                    throw FxTrace.Exception.AsError(new InvalidOperationException(SR2.FilterElementNotFound(entry.FilterName)));
                }
                MessageFilter filter = filterElement.CreateFilter(xmlNamespaces, filterElements);
                //retreive alternate service endpoints
                IList <ServiceEndpoint> endpoints = new List <ServiceEndpoint>();
                if (!string.IsNullOrEmpty(entry.BackupList))
                {
                    BackupEndpointCollection alternateEndpointListElement = routingSection.BackupLists[entry.BackupList];
                    if (alternateEndpointListElement == null)
                    {
                        throw FxTrace.Exception.AsError(new InvalidOperationException(SR2.BackupListNotFound(entry.BackupList)));
                    }
                    endpoints = alternateEndpointListElement.CreateAlternateEndpoints();
                }
                //add first endpoint to beginning of list
                endpoints.Insert(0, ClientEndpointLoader.LoadEndpoint(entry.EndpointName));
                routingTable.Add(filter, endpoints, entry.Priority);
            }

            return(routingTable);
        }
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            XPathMessageContext context = new XPathMessageContext();

            foreach (KeyValuePair <string, string> pair in this.namespaces)
            {
                context.AddNamespace(pair.Key, pair.Value);
            }
            return(context);
        }
예제 #3
0
        public RoutingTable()
        {
            this.filterTable           = new XPathMessageFilterTable <EndpointAddress>();
            this.randomNumberGenerator = new Random();

            XmlNamespaceManager manager = new XPathMessageContext();

            XmlReader        routingTableDataFileReader = XmlReader.Create(ConfigurationManager.AppSettings["routingTableXmlFile"]);
            RoutingTableData routingTableData           = (RoutingTableData) new XmlSerializer(typeof(RoutingTableData)).Deserialize(routingTableDataFileReader);

            foreach (RouterNamespace ns in routingTableData.RouterNamespacesSection.RouterNamespaces)
            {
                manager.AddNamespace(ns.Prefix, ns.NamespaceUri);
            }

            foreach (Route route in routingTableData.RoutesSection.Routes)
            {
                this.filterTable.Add(new XPathMessageFilter(route.XPath, manager), new EndpointAddress(route.Uri));
            }
        }
예제 #4
0
        private static void ConfigureRouterViaCode(ServiceHost serviceHost)
        {
            //This code sets up the Routing Sample via code.  Rename the provided app.config
            //to App.config.example and uncomment this method call to run a config-based Routing Service

            //set up some communication defaults
            //note that some of these are a little artifical for the purpose of demonstrating
            //different filter types and how to define them

            //the regular calculator service is located at net.tcp://localhost:9090/servicemodelsamples/service/
            string calcDestinationAddress = "net.tcp://localhost:9090/servicemodelsamples/service/";

            //the rounding calc service is located at net.tcp://localhost:8080/servicemodelsamples/service/
            string roundingDestinationAddress = "net.tcp://localhost:8080/servicemodelsamples/service/";

            //the "Default" router address
            string routerAddress = "http://localhost/routingservice/router/general";

            //the virtualized address of the regular calculator
            string virtualCalculatorAddress = "http://localhost/routingservice/router/regular/calculator";

            //the virtualized address of the rounding calculator
            string virtualRoundingCalculatorAddress = "http://localhost/routingservice/router/rounding/calculator";

            //set up the bindings for the Routing Service's communication with the client
            Binding routerBinding = new WSHttpBinding();

            //set up the bindings for the Routing Service's communication with the Calculator Services
            Binding clientBinding = new NetTcpBinding();

            //use the IRequestReplyRouter since the client and services are expecting request/response communication
            ContractDescription contract = ContractDescription.GetContract(typeof(IRequestReplyRouter));

            //set up the default Router endpoint
            ServiceEndpoint routerEndpoint = new ServiceEndpoint(contract, routerBinding, new EndpointAddress(routerAddress));

            routerEndpoint.Name = "routerEndpoint";

            //create the virtual endpoint for the regular CalculatorSerivice
            ServiceEndpoint calcEndpoint = new ServiceEndpoint(contract, routerBinding, new EndpointAddress(virtualCalculatorAddress));

            calcEndpoint.Name = "calculatorEndpoint";

            //create the virtual endpoint for the rounding CalculatorSerivice
            ServiceEndpoint roundingEndpoint = new ServiceEndpoint(contract, routerBinding, new EndpointAddress(virtualRoundingCalculatorAddress));

            roundingEndpoint.Name = "roundingEndpoint";

            //add the inbound endpoints that the Routing Service will listen for
            serviceHost.AddServiceEndpoint(routerEndpoint);
            serviceHost.AddServiceEndpoint(calcEndpoint);
            serviceHost.AddServiceEndpoint(roundingEndpoint);

            //create the client endpoints the router will route messages to
            ServiceEndpoint RegularCalcEndpoint  = new ServiceEndpoint(contract, new NetTcpBinding(), new EndpointAddress(calcDestinationAddress));
            ServiceEndpoint RoundingCalcEndpoint = new ServiceEndpoint(contract, new NetTcpBinding(), new EndpointAddress(roundingDestinationAddress));

            //create the endpoint lists that contains the service endpoints we want to route to
            List <ServiceEndpoint> RegularCalcs  = new List <ServiceEndpoint>();
            List <ServiceEndpoint> RoundingCalcs = new List <ServiceEndpoint>();

            //add the endpoints in the order we want the Routing Service to try sending to them
            RegularCalcs.Add(RegularCalcEndpoint);
            RoundingCalcs.Add(RoundingCalcEndpoint);

            //create the default RoutingConfiguration
            RoutingConfiguration rc = new RoutingConfiguration();

            //create all of the necessary filters

            //create a new XPathMessageFilter that will look for the custom header
            //Unfortunately, the default namespace manager doesn't have the custom namespace
            // that we use defined so we have to define that prefix ourselves.
            //Any message that shows up with this header will match this filter.
            XPathMessageContext namespaceManager = new XPathMessageContext();

            namespaceManager.AddNamespace("custom", "http://my.custom.namespace/");

            XPathMessageFilter xpathFilter = new XPathMessageFilter("sm:header()/custom:RoundingCalculator = 1", namespaceManager);

            //create a new Endpoint Name Message Filter, which will match any message that was received
            //on the calculator Endpoint.  The Endpoint name was defined when we created the service endpoint object
            EndpointNameMessageFilter endpointNameFilter = new EndpointNameMessageFilter("calculatorEndpoint");

            //Create a new Prefix Endpoint Address Message Filter.  This will match any message that showed up on an endpoint
            //with an address that matches the address -prefix- (or front portion) provided.  In this example we define
            //the address prefix as "http://localhost/routingservice/router/rounding/".  This means that any messages that arrive
            //addressed to http://localhost/routingservice/router/rounding/* will be matched by this filter.  In this case, that
            //will be messages that show up on the rounding calculator endpoint, which has the address of
            //http://localhost/routingservice/router/rounding/calculator.
            PrefixEndpointAddressMessageFilter prefixAddressFilter = new PrefixEndpointAddressMessageFilter(new EndpointAddress("http://localhost/routingservice/router/rounding/"));

            //create two new Custom message filters.  In this example, we're going to use a "RoundRobin" message filter
            //this message filter is created in the provided RoundRobinMessageFilter.cs file.  These filters, when set
            //to the same group, will alternate between reporting that they match the message and that they don't, such that
            //only one of them will respond true at a time.
            RoundRobinMessageFilter roundRobinFilter1 = new RoundRobinMessageFilter("group1");
            RoundRobinMessageFilter roundRobinFilter2 = new RoundRobinMessageFilter("group1");


            //Now let's add all of those Message Filters to the Message Filter Table
            //note the use of priorities to influence the order in which the MessageFilter Table
            //executes the filters.  The higher the priority, the sooner the filter will be
            //executed, the lower the priority, the later a filter will be executed.  Thus a filter
            //at priority 2 runs before a filter at priority 1.  The default priority level
            //if one isn't specified is 0.  A Message Filter Table executes all of the filters
            //at a given priority level before moving to the next lowest priority level.
            //If a match is found at a particular priority, then the Message Filter Table doesn't
            //continue trying to find matches at the next lower priority.
            //
            //While this example shows how to use Message Filter priorities, in general it is
            //more performant and better design to design and configure your filters such that they
            //don't require prioritization in order to function correctly.


            //The first filter we add is the XPath filter, and we set its priority to 2.
            //Thus this will be the first MessageFilter that executes.  If it finds the custom
            //header, regardless of what the results of the other filters would be, the message
            //will be routed to the Rounding Calculator endpoint.

            //catch messages that showed up with the custom header
            rc.FilterTable.Add(xpathFilter, RoundingCalcs, 2);

            //At priority 1, we'll add two filters.  These will only run if the xpath filter
            //at priority 2 doesn't match the message.  These two filters show two different ways to
            //determine where the message was addressed when it showed up.  Because they effectively check
            //to see if the message arrived at one of the two endpoints, we can run them
            //at the same priority level since they're never going to both return true.

            //find messages that showed up addressed to the specific virtual endpoints
            rc.FilterTable.Add(endpointNameFilter, RegularCalcs, 1);
            rc.FilterTable.Add(prefixAddressFilter, RoundingCalcs, 1);

            //Finally, run the RoundRobin message filters.  Since we configured the filters
            //with the same group name, only one of them will match at a time.  Since we've already
            //Routed all the messages with the custom header, and then those addressed to the specific
            //virtualized endpoints, these will only be messages that showed up addressed to the
            //default router endpoint without the custom header.  Since these will switch based
            //on a per message call, half of the operations will go to the regular calculator, and
            //half will go to the Rounding calculator.
            rc.FilterTable.Add(roundRobinFilter1, RegularCalcs, 0);
            rc.FilterTable.Add(roundRobinFilter2, RoundingCalcs, 0);

            //create the Routing Behavior with the Routing Configuration and add it to the
            //serviceHost's Description.
            serviceHost.Description.Behaviors.Add(new RoutingBehavior(rc));
        }
예제 #5
0
        private static Activity GetPropertyWorkflow()
        {
            // Correlation handle used to link operations together
            Variable <CorrelationHandle> operationHandle = new Variable <CorrelationHandle>();

            // The generated property Id
            Variable <Guid> propertyId = new Variable <Guid>();

            // Variable used to indicate that the workflow should finish
            Variable <bool> finished = new Variable <bool>("Finished", false);

            Variable <string> address     = new Variable <string>();
            Variable <string> owner       = new Variable <string>();
            Variable <double> askingPrice = new Variable <double>();

            // Initial receive - this kicks off the workflow
            Receive receive = new Receive
            {
                CanCreateInstance   = true,
                OperationName       = "UploadPropertyInformation",
                ServiceContractName = XName.Get("IProperty", ns),
                Content             = new ReceiveParametersContent
                {
                    Parameters =
                    {
                        { "address",     new OutArgument <string>(address)     },
                        { "owner",       new OutArgument <string>(owner)       },
                        { "askingPrice", new OutArgument <double>(askingPrice) }
                    }
                }
            };

            // Define the local namespace
            XPathMessageContext messageContext = new XPathMessageContext();

            messageContext.AddNamespace("local", ns);

            // Extracts the guid sent back to the client on the initial response
            MessageQuerySet extractGuid = new MessageQuerySet
            {
                { "PropertyId", new XPathMessageQuery("sm:body()/ser:guid", messageContext) }
            };

            // Extracts the guid sent up with the property image
            MessageQuerySet extractGuidFromUploadRoomInformation = new MessageQuerySet
            {
                { "PropertyId", new XPathMessageQuery(@"sm:body()/local:UploadRoomInformation/local:propertyId", messageContext) }
            };

            // Receive used to indicate that the upload is complete
            Receive receiveDetailsComplete = new Receive
            {
                OperationName       = "DetailsComplete",
                ServiceContractName = XName.Get("IProperty", ns),
                CorrelatesWith      = operationHandle,
                CorrelatesOn        = extractGuid,
                Content             = ReceiveContent.Create(new OutArgument <Guid>(propertyId))
            };

            Variable <string> roomName = new Variable <string>();
            Variable <double> width    = new Variable <double>();
            Variable <double> depth    = new Variable <double>();

            // Receive room information
            Receive receiveRoomInfo = new Receive
            {
                OperationName       = "UploadRoomInformation",
                ServiceContractName = XName.Get("IProperty", ns),
                CorrelatesWith      = operationHandle,
                CorrelatesOn        = extractGuidFromUploadRoomInformation,
                Content             = new ReceiveParametersContent
                {
                    Parameters =
                    {
                        { "propertyId", new OutArgument <Guid>()           },
                        { "roomName",   new OutArgument <string>(roomName) },
                        { "width",      new OutArgument <double>(width)    },
                        { "depth",      new OutArgument <double>(depth)    },
                    }
                }
            };

            return(new Sequence
            {
                Variables = { propertyId, operationHandle, finished, address, owner, askingPrice },
                Activities =
                {
                    receive,
                    new WriteLine {
                        Text = "Assigning a unique ID"
                    },
                    new Assign <Guid>
                    {
                        To = new OutArgument <Guid> (propertyId),
                        Value = new InArgument <Guid> (Guid.NewGuid())
                    },
                    new WriteLine  {
                        Text = new InArgument <string> (env => string.Format("{0} is selling {1} for {2}.\r\nAssigned unique id {3}.",owner.Get(env),                                                                                                            address.Get(env), askingPrice.Get(env), propertyId.Get(env)))
                    },
                    new SendReply
                    {
                        Request = receive,
                        Content = SendContent.Create(new InArgument <Guid> (env => propertyId.Get(env))),
                        CorrelationInitializers =
                        {
                            new QueryCorrelationInitializer
                            {
                                CorrelationHandle = operationHandle,
                                MessageQuerySet = extractGuid
                            }
                        }
                    },
                    new While
                    {
                        Condition = ExpressionServices.Convert <bool>(env => !finished.Get(env)),
                        Body = new Pick
                        {
                            Branches =
                            {
                                new PickBranch
                                {
                                    Variables =           { roomName,                 width,depth                                                                                                                     },
                                    Trigger = receiveRoomInfo,
                                    Action = new WriteLine{
                                        Text = new InArgument <string> (env => string.Format("Room '{0}' uploaded, dimensions {1}W x {2}D",roomName.Get(env),                                                                                                         width.Get(env),   depth.Get(env)))
                                    },
                                },
                                new PickBranch
                                {
                                    Trigger = receiveDetailsComplete,
                                    Action = new Sequence
                                    {
                                        Activities =
                                        {
                                            new Assign <bool>
                                            {
                                                To = new OutArgument <bool>(finished),
                                                Value = new InArgument <bool>(true)
                                            },
                                            new WriteLine {
                                                Text = "Property Details Complete"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    new WriteLine {
                        Text = "Finished!"
                    }
                }
            });
        }
예제 #6
0
        static WorkflowService GetService()
        {
            Variable <Customer>          customer     = new Variable <Customer>();
            Variable <Order>             order        = new Variable <Order>();
            Variable <string>            drug         = new Variable <string>();
            Variable <double>            adjustedCost = new Variable <double>();
            Variable <int>               percentagePaidByInsurance = new Variable <int>();
            Variable <CorrelationHandle> customerHandle            = new Variable <CorrelationHandle>();
            Variable <CorrelationHandle> orderHandle = new Variable <CorrelationHandle>();

            XPathMessageContext pathContext = new XPathMessageContext();

            pathContext.AddNamespace("psns", Constants.PharmacyServiceNamespace);

            // <Snippet2>
            MessageQuerySet GetOrderQuerySet = new MessageQuerySet
            {
                {
                    "OrderID",
                    new XPathMessageQuery("//psns:Order/psns:OrderID", pathContext)
                }
            };
            // </Snippet2>
            MessageQuerySet GetOrderIDQuerySet = new MessageQuerySet
            {
                {
                    "OrderID",
                    new XPathMessageQuery("//ser:guid", pathContext)
                }
            };

            MessageQuerySet customerQuerySet = new MessageQuerySet
            {
                {
                    "CustomerID",
                    new XPathMessageQuery("//psns:GetBaseCost/psns:Customer/psns:CustomerID", pathContext)
                }
            };

            MessageQuerySet customerIDQuerySet = new MessageQuerySet
            {
                {
                    "CustomerID",
                    new XPathMessageQuery("//ser:guid", pathContext)
                }
            };

            // This will use implicit correlation within the workflow using the WorkflowServiceHost's default CorrelationHandle
            // <Snippet3>
            Receive prescriptionRequest = new Receive
            {
                DisplayName         = "Request Perscription",
                OperationName       = "GetBaseCost",
                ServiceContractName = Constants.PharmacyServiceContractName,
                CanCreateInstance   = true,
                //CorrelatesWith = customerHandle,  -- add this line for explicit correlation
                CorrelatesOn = customerQuerySet,
                Content      = new ReceiveParametersContent
                {
                    Parameters =
                    {
                        { "Customer", new OutArgument <Customer>(customer) },
                        { "Drug",     new OutArgument <string>(drug)       },
                    }
                }
            };
            // </Snippet3>

            // This will use implicit correlation within the workflow using the WorkflowServiceHost's default CorrelationHandle
            Receive GetInsurancePaymentPercentageRequest = new Receive
            {
                DisplayName         = "Get Insurance Coverage",
                ServiceContractName = Constants.PharmacyServiceContractName,
                OperationName       = "GetInsurancePaymentPercentage",
                CanCreateInstance   = true,
                //CorrelatesWith = customerHandle,  -- add this line for explicit correlation
                CorrelatesOn = customerIDQuerySet,
                Content      = ReceiveContent.Create(new OutArgument <Guid>())
            };

            // This will explicitly correlate with the SendReply action after the prescriptionRequest using the OrderID (stored in the orderHandle)
            Receive GetAdjustedCostRequest = new Receive
            {
                DisplayName         = "Get Adjusted Cost",
                OperationName       = "GetAdjustedCost",
                ServiceContractName = Constants.PharmacyServiceContractName,
                CanCreateInstance   = true,
                CorrelatesOn        = GetOrderIDQuerySet,
                CorrelatesWith      = orderHandle,
                Content             = ReceiveContent.Create(new OutArgument <Guid>())
            };

            Activity PrescriptonWorkflow = new Sequence()
            {
                Variables  = { customer, order, drug, percentagePaidByInsurance, adjustedCost, customerHandle, orderHandle },
                Activities =
                {
                    new WriteLine
                    {
                        Text = "Beginning Workflow"
                    },

                    new Parallel
                    {
                        Branches =
                        {
                            new Sequence
                            {
                                Activities =
                                {
                                    GetInsurancePaymentPercentageRequest,
                                    new Assign <int>
                                    {
                                        To    = new OutArgument <int>((e) => percentagePaidByInsurance.Get(e)),
                                        Value = new InArgument <int>((e) => new Random().Next(0, 100))
                                    },
                                    new SendReply
                                    {
                                        DisplayName = "Return Percentage",
                                        Request     = GetInsurancePaymentPercentageRequest,
                                        Content     = SendContent.Create(new InArgument <int>((e) => percentagePaidByInsurance.Get(e)))
                                    }
                                }
                            },

                            new Sequence
                            {
                                Activities =
                                {
                                    prescriptionRequest,
                                    new WriteLine
                                    {
                                        Text = new InArgument <string>(env => (string.Format("{0}, {1}\t{2}",customer.Get(env).LastName,                                                       customer.Get(env).FirstName, customer.Get(env).CustomerID.ToString())))
                                    },
                                    new Assign <Order>
                                    {
                                        To    = new OutArgument <Order>(order),
                                        Value = new InArgument <Order>((e) => new Order()
                                        {
                                            CustomerID = customer.Get(e).CustomerID,Drug = drug.Get(e),                                                               OrderID = Guid.NewGuid()
                                        })
                                    },
                                    new WriteLine
                                    {
                                        Text = new InArgument <string>(env => (string.Format("OrderID: {0}",order.Get(env).OrderID.ToString())))
                                    },
                                    new Assign <int>
                                    {
                                        To    = new OutArgument <int>((e) => order.Get(e).Cost),
                                        Value = new InArgument <int>((e) => new Random().Next(20,                   50))
                                    },
                                    // <Snippet0>
                                    new SendReply
                                    {
                                        DisplayName = "Send Adjusted Cost",
                                        Request     = prescriptionRequest,
                                        // Initialize the orderHandle using the MessageQuerySet to correlate with the final GetAdjustedCost request
                                        CorrelationInitializers =
                                        {
                                            // <Snippet1>
                                            new QueryCorrelationInitializer
                                            {
                                                CorrelationHandle = orderHandle,
                                                MessageQuerySet   = GetOrderQuerySet
                                            }
                                            // </Snippet1>
                                        },
                                        Content = SendContent.Create(new InArgument <Order>((e) => order.Get(e)))
                                    }
                                    // </Snippet0>
                                }
                            }
                        }
                    },

                    new Assign <double>
                    {
                        To    = new OutArgument <double>((e) => adjustedCost.Get(e)),
                        Value = new InArgument <double>((e) => order.Get(e).Cost *(100 - percentagePaidByInsurance.Get(e)) * .01)
                    },
                    new WriteLine
                    {
                        Text = new InArgument <string>(env => (string.Format("Base Cost: ${0}", order.Get(env).Cost.ToString())))
                    },
                    new WriteLine
                    {
                        Text = new InArgument <string>(env => (string.Format("Insurance Coverage: {0}%", percentagePaidByInsurance.Get(env).ToString())))
                    },
                    new WriteLine
                    {
                        Text = new InArgument <string>(env => (string.Format("Adjusted Cost: ${0}", decimal.Round(Convert.ToDecimal(adjustedCost.Get(env)), 2))))
                    },
                    GetAdjustedCostRequest,
                    new SendReply
                    {
                        Request = GetAdjustedCostRequest,
                        Content = SendContent.Create(new InArgument <double>((e) => adjustedCost.Get(e)))
                    },
                    new WriteLine
                    {
                        Text = "Workflow Completed"
                    }
                }
            };

            WorkflowService service = new WorkflowService
            {
                Name = "PharmacyService",
                Body = PrescriptonWorkflow,
                ConfigurationName = "PharmacyService"
            };

            return(service);
        }
예제 #7
0
        void OnTypeSelectionChanged(object sender, RoutedEventArgs e)
        {
            var contentCorrelationDesigner = (ContentCorrelationTypeExpander)sender;

            //is selection valid (valid type or property)
            if (contentCorrelationDesigner.IsSelectionValid)
            {
                var path = contentCorrelationDesigner.GetMemberPath();
                var type = contentCorrelationDesigner.GetSelectedType();
                try
                {
                    XmlNamespaceManager namespaceManager = null;
                    string xpathQuery = string.Empty;
                    var    content    = this.Activity.Properties["Content"].Value;
                    if (content.IsAssignableFrom <ReceiveMessageContent>() || content.IsAssignableFrom <SendMessageContent>())
                    {
                        //generating xpath for message content
                        xpathQuery = XPathQueryGenerator.CreateFromDataContractSerializer(type, path, out namespaceManager);
                    }
                    else
                    {
                        //generating xpath for parameter content
                        XName  serviceContractName = null;
                        string operationName       = null;
                        string parameterName       = contentCorrelationDesigner.SelectedTypeEntry.Name;
                        bool   isReply             = this.Activity.IsAssignableFrom <SendReply>() || this.Activity.IsAssignableFrom <ReceiveReply>();
                        if (isReply)
                        {
                            operationName       = (string)this.Activity.Properties["Request"].Value.Properties["OperationName"].ComputedValue;
                            serviceContractName = (XName)this.Activity.Properties["Request"].Value.Properties["ServiceContractName"].ComputedValue;

                            if (string.IsNullOrEmpty(operationName) || null == serviceContractName)
                            {
                                ModelItem requestDisplayName;
                                this.Activity.TryGetPropertyValue(out requestDisplayName, "Request", "DisplayName");
                                throw FxTrace.Exception.AsError(new InvalidOperationException(
                                                                    string.Format(CultureInfo.CurrentUICulture, (string)this.FindResource("parametersRequiredText"), requestDisplayName.GetCurrentValue())));
                            }
                        }
                        else
                        {
                            operationName       = (string)this.Activity.Properties["OperationName"].ComputedValue;
                            serviceContractName = (XName)this.Activity.Properties["ServiceContractName"].ComputedValue;

                            if (string.IsNullOrEmpty(operationName) || null == serviceContractName)
                            {
                                throw FxTrace.Exception.AsError(new InvalidOperationException(
                                                                    string.Format(CultureInfo.CurrentUICulture, (string)this.FindResource("parametersRequiredText"), this.Activity.Properties["DisplayName"].ComputedValue)));
                            }
                        }
                        xpathQuery = ParameterXPathQueryGenerator.CreateFromDataContractSerializer(serviceContractName, operationName, parameterName, isReply, type, path, out namespaceManager);
                    }
                    //use CDF api to build a xpath out of type and its properties
                    string xpath = string.Format(CultureInfo.InvariantCulture, "sm:body(){0}", xpathQuery);

                    //get the context
                    //We need to copy over the namespaces from the manager's table 1 by 1. According to MSDN:
                    //If you specify an existing name table, any namespaces in the name table are not automatically added to XmlNamespaceManager.
                    //You must use AddNamespace and RemoveNamespace to add or remove namespaces.
                    XPathMessageContext messageContext = new XPathMessageContext();
                    foreach (string prefix in namespaceManager)
                    {
                        if (!string.IsNullOrEmpty(prefix) && !messageContext.HasNamespace(prefix) && prefix != "xmlns")
                        {
                            messageContext.AddNamespace(prefix, namespaceManager.LookupNamespace(prefix));
                        }
                    }

                    var typeEntry = (ExpanderTypeEntry)contentCorrelationDesigner.Tag;
                    //construct xpath
                    XPathMessageQuery query = new XPathMessageQuery(xpath, messageContext);
                    //store the xpath in the Tag property; this combo's selectedValue is bound to i
                    typeEntry.Tag       = query;
                    this.SelectedIndex  = 0;
                    this.IsDropDownOpen = false;
                    this.Query          = query;
                    this.RaiseEvent(new RoutedEventArgs(XPathCreatedEvent, this));
                }
                catch (Exception err)
                {
                    MessageBox.Show(
                        err.Message,
                        (string)this.Resources["controlTitle"],
                        MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }