예제 #1
0
        static void Main(string[] args)
        {
            // Create the WcfClient connector
            WcfConnectionStringBuilder builder = new WcfConnectionStringBuilder();

            builder.EndpointName = "ApplicationClient";
            WcfClientConnector client = new WcfClientConnector(builder.GenerateConnectionString()); // Endpoint name should match the ep name in app.config

            // Setup the formatter
            client.Formatter = new MARC.Everest.Formatters.XML.ITS1.Formatter();
            client.Formatter.GraphAides.Add(new DatatypeFormatter());

            // We want the service to validate our messages, not the formatter, so lets just turn off the
            // formatter validation for now
            (client.Formatter as MARC.Everest.Formatters.XML.ITS1.Formatter).ValidateConformance = false;

            // Open the connection
            client.Open();

            // Start the async send
            IAsyncResult iaSendResult = client.BeginSend(CreateInstance(), null, null);

            Console.WriteLine("Formatting and sending, please wait...");
            iaSendResult.AsyncWaitHandle.WaitOne(); // Wait until the response is received

            // Now we have to check that the message was actually sent to the remote system
            WcfSendResult sndResult = client.EndSend(iaSendResult) as WcfSendResult;

            // The result of sending the message wasn't good.
            if (sndResult.Code != ResultCode.Accepted && sndResult.Code != ResultCode.AcceptedNonConformant)
            {
                Console.WriteLine("The message wasn't sent!");
            }
            else // The connector has sent the message
            {
                // Receive the result (this involves waiting...)
                IAsyncResult iaRcvResult = client.BeginReceive(sndResult, null, null);
                Console.WriteLine("Parsing result...");
                iaRcvResult.AsyncWaitHandle.WaitOne(); // Wait for deserialization
                WcfReceiveResult rcvResult = client.EndReceive(iaRcvResult) as WcfReceiveResult;

                // Now lets print out the structure
                client.Formatter.Graph(Console.OpenStandardOutput(), rcvResult.Structure);
            }

            // Close the connection
            client.Close();

            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }
예제 #2
0
        public System.ServiceModel.Channels.Message ProcessInboundMessage(System.ServiceModel.Channels.Message m)
        {
            #if DEBUG
            Trace.TraceInformation("Received message on transport...");
            #endif

            if (ListenConnector == null && OperationContext.Current.Host is WcfServiceHost)
            {
                ListenConnector = (OperationContext.Current.Host as WcfServiceHost).ConnectorHost;
            }

            if (ListenConnector != null) // In process
            {
                // Is this channel one way or two way?
                if (!(OperationContext.Current.Channel is IOutputChannel)) // Input only
                {
                    return(null);
                }

                #if DEBUG
                Trace.TraceInformation("Message handoff to WcfServerConnector completed");
                #endif

                WcfSendResult processResult = ListenConnector.ProcessMessage(m);
                Message       retVal        = null;

                // There is an error, so the return value must be a fault!
                if (processResult == null || processResult.Code != ResultCode.Accepted && processResult.Code != ResultCode.AcceptedNonConformant)
                {
                    // Web based context?
                    if (WebOperationContext.Current != null)
                    {
                        WebOperationContext.Current.OutgoingResponse.StatusCode        = System.Net.HttpStatusCode.InternalServerError;
                        WebOperationContext.Current.OutgoingResponse.StatusDescription = "Internal Server Error";
                    }

                    List <String> details = new List <string>();
                    if (processResult != null)
                    {
                        details = new List <String>();
                        foreach (var dtl in processResult.Details)
                        {
                            details.Add(dtl.Message); // Append details
                        }
                    }

                    if (processResult == null)
                    {
                        retVal = Message.CreateMessage(m.Version, MessageFault.CreateFault(FaultCode.CreateReceiverFaultCode(processResult.Code.ToString(), "http://marc.mohawkcollege.ca/hi"), new FaultReason("The receiver has constructed an invalid response that cannot be sent to the sender"), details), m.Headers.Action);
                    }
                    else
                    {
                        retVal = Message.CreateMessage(m.Version, MessageFault.CreateFault(FaultCode.CreateSenderFaultCode("EPIC", "http://marc.mohawkcollege.ca/hi"), new FaultReason("Catastrophic failure occurred in the WcfServer send pipeline. This usually occurs when the connector does not receive a message in the allocated amount of time"), details), m.Headers.Action);
                    }
                }
                else
                {
                    retVal = processResult.Message;

                    if (processResult.Headers != null)
                    {
                        retVal.Headers.Clear();
                        retVal.Headers.CopyHeadersFrom(processResult.Headers);
                    }
                }

                #if DEBUG
                Trace.TraceInformation("Message sent to client");
                #endif

                return(retVal);
            }
            else
            {
                // Get settings
                if (settings == null)
                {
                    settings = System.Web.Configuration.WebConfigurationManager.GetSection("marc.everest.connectors.wcf") as MARC.Everest.Connectors.WCF.Configuration.ConfigurationSection;
                }

                // Now format the message and pass it on ...
                MemoryStream         ms = new MemoryStream();
                System.Xml.XmlWriter xw = System.Xml.XmlWriter.Create(ms); // Write to message memory stream for classification matching
                m.WriteMessage(xw);
                xw.Flush();                                                // Flush the Xml Writer

                ms.Seek(0, SeekOrigin.Begin);                              // Seek to start
                XPathDocument  xpd = new XPathDocument(ms);                // load xpath document
                XPathNavigator xpn = xpd.CreateNavigator();

                IMessageReceiver receiver = null; // The receiver to use

                // Determine the receiver
                foreach (KeyValuePair <String, IMessageReceiver> kv in settings.Receiver)
                {
                    if (xpn.SelectSingleNode(kv.Key) != null)
                    {
                        receiver = kv.Value;
                        break;
                    }
                }

                // Was a receiver found?
                if (receiver == null)
                {
                    // Create a not implemented exception
                    if (WebOperationContext.Current != null)
                    {
                        WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.NotImplemented;
                    }
                    return(Message.CreateMessage(m.Version, MessageFault.CreateFault(FaultCode.CreateSenderFaultCode(
                                                                                         "NotImplemented", "http://marc.mohawkcollege.ca/hi"), new FaultReason("No receiver understands the request message.")),
                                                 m.Headers.Action));
                }

                // Create a streams for deserialization
                ms = new MemoryStream();
                XmlWriterSettings xws = new XmlWriterSettings();
                xws.Indent = true;
                xw         = XmlWriter.Create(ms, xws);

                // Deserialize body
                WcfReceiveResult rcv = new WcfReceiveResult();
                try
                {
                    // Because of classification, we need to process this in a wierd way,
                    // Basically the formatter will classify the message based on the root element name
                    // it receives. Because a SOAP message's root isn't what we really want to process,
                    // the first child node under the 'body' must be passed to the xml writer
                    xpn.SelectSingleNode("//*[local-name() = 'Body']/child::node()").WriteSubtree(xw);
                    xw.Flush();
                    ms.Seek(0, SeekOrigin.Begin);

                    var serResult = settings.Formatter.Parse(ms);
                    rcv.Structure = serResult.Structure;
                    rcv.Details   = serResult.Details;
                    if (rcv.Details.Count() == 0)
                    {
                        rcv.Code = ResultCode.Accepted;
                    }
                    else
                    {
                        rcv.Code = ResultCode.AcceptedNonConformant;
                    }
                }
                catch (Exception e)
                {
                    rcv.Code    = ResultCode.Error;
                    rcv.Details = new IResultDetail[] { new ResultDetail(ResultDetailType.Error, e.Message, e) };
                }

                // Process on the receiver
                IGraphable obj = receiver.MessageReceived(rcv.Structure, rcv.Code, rcv.Details);

                // Graph this back
                XmlSerializerSurrogate surrogate = new XmlSerializerSurrogate((IXmlStructureFormatter)settings.Formatter);

                // Serialize the response
                Message result = Message.CreateMessage(m.Version, m.Headers.Action, obj, surrogate);

                // Validate
                surrogate.WriteObject(new MemoryStream(), obj);

                // Surrogate result code is acceptable?
                if (surrogate.ResultCode != ResultCode.Accepted && surrogate.ResultCode != ResultCode.AcceptedNonConformant)
                {
                    if (WebOperationContext.Current != null)
                    {
                        WebOperationContext.Current.OutgoingResponse.StatusCode        = System.Net.HttpStatusCode.InternalServerError;
                        WebOperationContext.Current.OutgoingResponse.StatusDescription = "Internal Server Error";
                    }

                    List <string> details = new List <String>();
                    foreach (var itm in surrogate.Details)
                    {
                        details.Add(itm.Message); // Append details
                    }
                    return(Message.CreateMessage(m.Version, MessageFault.CreateFault(FaultCode.CreateReceiverFaultCode(surrogate.ResultCode.ToString(), "http://marc.mohawkcollege.ca/hi"), new FaultReason("The receiver has constructed an invalid response that cannot be returned to the sender"), details), m.Headers.Action));
                }
                else
                {
                    return(result);
                }
            }
        }