public void WorkReceive(object state)
            {
                WcfReceiveResult result = new WcfReceiveResult();

                // Create the surrogate
                XmlSerializerSurrogate surrogate = new XmlSerializerSurrogate(Formatter);

                try
                {
                    // Parse the object
                    result.MessageIdentifier = MessageId;

                    result.MessageVersion = (state as Message).Version;
                    result.Structure      = (state as Message).GetBody <IGraphable>(surrogate);
                    result.Headers        = (state as Message).Headers;
                    result.Details        = surrogate.Details;
                    result.Code           = ResultCode.Accepted;
                    if (result.Details.FirstOrDefault(o => o.Type == ResultDetailType.Error) != null)
                    {
                        result.Code = ResultCode.AcceptedNonConformant;
                    }
                    else if (result.Structure == null)
                    {
                        result.Code = ResultCode.TypeNotAvailable;
                    }
                }
                catch (MessageValidationException e)
                {
                    result.Code = ResultCode.Rejected;
                    List <IResultDetail> dtl = new List <IResultDetail>(new IResultDetail[] { new ResultDetail(ResultDetailType.Error, e.Message, e) });
                    dtl.AddRange(surrogate.Details ?? new IResultDetail[0]);
                    result.Details = dtl.ToArray();
                }
                catch (FormatException e)
                {
                    result.Code    = ResultCode.Rejected;
                    result.Details = new IResultDetail[] { new ResultDetail(ResultDetailType.Error, e.Message, e) };
                }
                catch (Exception e)
                {
                    result.Code    = ResultCode.Error;
                    result.Details = new IResultDetail[] { new ResultDetail(ResultDetailType.Error, e.Message, e) };
                }


                // Set the result
                this.ReceiveResult = result;

                // Fire completed event
                if (Completed != null)
                {
                    Completed(this);
                }
            }
Beispiel #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);
                }
            }
        }
Beispiel #3
0
            public void WorkSend(object state)
            {
                // Prepare stream
                SendResult = new WcfSendResult();
                IGraphable data = null;

                ReceiveResult = new WcfReceiveResult();
                try { data = (IGraphable)state; }
                catch { }


                // Prepare the serializer surrogate
                XmlSerializerSurrogate surrogate = new XmlSerializerSurrogate(Formatter);

                try
                {
                    if (data == null)
                    {
                        throw new MessageValidationException("Invalid message structure passed to the connector", data);
                    }

                    // Graph the object
                    string soapAction = "";
#if WINDOWS_PHONE
                    SendResult.Message = Message.CreateMessage(MessageVersion, Actions != null && Actions.TryGetValue(state.GetType(), out soapAction) ? soapAction : "none", data, surrogate);
#else
                    SendResult.Message = Message.CreateMessage(MessageVersion, WcfConfiguration != null && WcfConfiguration.Actions.TryGetValue(state.GetType().FullName, out soapAction) ? soapAction : "none", data, surrogate);
#endif
                    if (CustomHeaders != null)
                    {
                        SendResult.Message.Headers.CopyHeadersFrom(CustomHeaders);
                    }
                    // Validate
#if !WINDOWS_PHONE
                    var graphResult = this.Formatter.Graph(new MemoryStream(), data);
                    SendResult.Code    = graphResult.Code;
                    SendResult.Details = graphResult.Details;
                    // Did the operation fail?
                    if (graphResult.Code != ResultCode.Accepted && graphResult.Code != ResultCode.AcceptedNonConformant)
                    {
                        if (InvalidMessage != null)
                        {
                            MessageEventArgs me = new MessageEventArgs(SendResult.Code, surrogate.Details);
                            InvalidMessage(this, me);
                            if (me.Alternate != null)
                            {
                                SendResult.Message = Message.CreateMessage(MessageVersion, soapAction, me.Alternate, surrogate);
                                graphResult        = this.Formatter.Graph(new MemoryStream(), data);
                                SendResult.Code    = graphResult.Code;
                                SendResult.Details = graphResult.Details;
                            }
                        }
                        else
                        {
                            SendResult.Details = graphResult.Details;
                            SendResult.Message = null;
                        }
                    }
#endif
                }
                catch (MessageValidationException e)
                {
                    SendResult.Code = ResultCode.Rejected;
                    List <IResultDetail> dtl = new List <IResultDetail>(new IResultDetail[] { new ResultDetail(ResultDetailType.Error, e.Message, e) });
                    dtl.AddRange(surrogate.Details ?? new IResultDetail[0]);
                    SendResult.Details = dtl.ToArray();
                }
                catch (FormatException e)
                {
                    SendResult.Code    = ResultCode.Rejected;
                    SendResult.Details = new IResultDetail[] { new ResultDetail(ResultDetailType.Error, e.Message, e) };
                }
                catch (Exception e)
                {
                    SendResult.Code    = ResultCode.Error;
                    SendResult.Details = new IResultDetail[] { new ResultDetail(ResultDetailType.Error, e.Message, e) };
                }
                finally
                {
                }

                // Fire completed event
                if (Completed != null)
                {
                    Completed(this);
                }
            }
            public void WorkSend(object state)
            {
                // Prepare stream
                WcfSendResult result = new WcfSendResult();
                IGraphable    data   = (IGraphable)state;

                // Create the surrogate
                XmlSerializerSurrogate surrogate = new XmlSerializerSurrogate(Formatter);

                try
                {
                    // Graph the object
                    result.Message   = Message.CreateMessage(MessageVersion, "", data, surrogate);
                    result.MessageId = this.MessageId;
                    result.Headers   = this.ResponseHeaders;

                    // Validate
                    surrogate.WriteObject(new MemoryStream(), data);
                    result.Code    = surrogate.ResultCode;
                    result.Details = surrogate.Details;

                    if ((result.Code != ResultCode.Accepted && result.Code != ResultCode.AcceptedNonConformant) &&
                        InvalidResponse != null)
                    {
                        MessageEventArgs mea = new MessageEventArgs(result.Code, result.Details);
                        InvalidResponse(this, mea);
                        InvalidResponse = null;                             // Don't call retry again! NOTE: This is a single use class.
                        if (mea.Alternate != null)
                        {                                                   // An alternate was suggested
                            if (Formatter is IValidatingStructureFormatter) // Turn of validation for fallback
                            {
                                (Formatter as IValidatingStructureFormatter).ValidateConformance = false;
                            }
                            WorkSend(mea.Alternate);
                        }
                        return;
                    }

                    // Did the operation succeed?
                    if (result.Code != ResultCode.Accepted && result.Code != ResultCode.AcceptedNonConformant)
                    {
                        result.Details = surrogate.Details;
                        result.Message = null;
                    }
                }
                catch (MessageValidationException e)
                {
                    result.Code = ResultCode.Rejected;
                    List <IResultDetail> dtl = new List <IResultDetail>(new IResultDetail[] { new ResultDetail(ResultDetailType.Error, e.Message, e) });
                    dtl.AddRange(surrogate.Details ?? new IResultDetail[0]);
                    result.Details = dtl.ToArray();
                }
                catch (FormatException e)
                {
                    result.Code    = ResultCode.Rejected;
                    result.Details = new IResultDetail[] { new ResultDetail(ResultDetailType.Error, e.Message, e) };
                }
                catch (Exception e)
                {
                    result.Code    = ResultCode.Error;
                    result.Details = new IResultDetail[] { new ResultDetail(ResultDetailType.Error, e.Message, e) };
                }
                finally
                {
                    // Set the result
                    this.SendResult = result;

                    // Fire completed event
                    if (Completed != null)
                    {
                        Completed(this);
                    }
                }
            }