Beispiel #1
0
        /// <summary>
        /// Helper message to write an error response message in case of an exception.
        /// </summary>
        /// <param name="exception">
        /// The exception that caused the failure.
        /// </param>
        /// <param name="statusCode">
        /// The HTTP status code that shall be returned to the caller.
        /// </param>
        /// <param name="serviceProvider">
        /// The DI container.
        /// </param>
        /// <param name="httpContext">
        /// The HTTP context that received the response message.
        /// </param>
        /// <returns>
        /// Returns the constructed message (which is implicitly written to the response
        /// and therefore must not be handled by the caller).
        /// </returns>
        private Message WriteErrorResponseMessage(
            Exception exception,
            int statusCode,
            IServiceProvider serviceProvider,
            HttpContext httpContext)
        {
            Message responseMessage;

            // Create response message

            string errorText   = exception.InnerException != null ? exception.InnerException.Message : exception.Message;;
            var    transformer = serviceProvider.GetService <ExceptionTransformer>();

            if (transformer != null)
            {
                errorText = transformer.Transform(exception);
            }

            var bodyWriter = new FaultBodyWriter(new Fault {
                FaultString = errorText
            });

            responseMessage = Message.CreateMessage(_messageEncoder.MessageVersion, null, bodyWriter);
            responseMessage = new CustomMessage(responseMessage);

            httpContext.Response.ContentType           = httpContext.Request.ContentType;
            httpContext.Response.Headers["SOAPAction"] = responseMessage.Headers.Action;
            httpContext.Response.StatusCode            = statusCode;
            _messageEncoder.WriteMessage(responseMessage, httpContext.Response.Body);

            return(responseMessage);
        }
Beispiel #2
0
        /// <summary>
        /// Returns an error response message with a predefined error text.
        /// </summary>
        /// <param name="errorText">
        /// The error text that is added to the response message.
        /// </param>
        /// <param name="statusCode">
        /// The HTTP status code that shall be returned to the caller.
        /// </param>
        /// <param name="httpContext">
        /// The HTTP context that received the response message.
        /// </param>
        /// <returns>
        /// Returns the constructed message (which is implicitly written to the response
        /// and therefore must not be handled by the caller).
        /// </returns>
        private Message WriteErrorResponseMessage(
            string errorText,
            int statusCode,
            HttpContext httpContext)
        {
            Message responseMessage;

            var bodyWriter = new FaultBodyWriter(new Fault {
                FaultString = errorText
            });

            responseMessage = Message.CreateMessage(_messageEncoder.MessageVersion, null, bodyWriter);
            responseMessage = new CustomMessage(responseMessage);

            httpContext.Response.ContentType           = httpContext.Request.ContentType;
            httpContext.Response.Headers["SOAPAction"] = responseMessage.Headers.Action;
            httpContext.Response.StatusCode            = statusCode;
            _messageEncoder.WriteMessage(responseMessage, httpContext.Response.Body);

            return(responseMessage);
        }
Beispiel #3
0
        private async Task <Message> ProcessOperation(HttpContext httpContext, IServiceProvider serviceProvider)
        {
            Message responseMessage;

            //Reload the body to ensure we have the full message
            using (var reader = new StreamReader(httpContext.Request.Body))
            {
                var body = await reader.ReadToEndAsync();

                var requestData = Encoding.UTF8.GetBytes(body);
                httpContext.Request.Body = new MemoryStream(requestData);
            }

            //Return metadata if no request
            if (httpContext.Request.Body.Length == 0)
            {
                return(ProcessMeta(httpContext));
            }

            //Get the message
            var requestMessage = _messageEncoder.ReadMessage(httpContext.Request.Body, 0x10000, httpContext.Request.ContentType);

            var soapAction = (httpContext.Request.Headers["SOAPAction"].FirstOrDefault() ?? requestMessage.GetReaderAtBodyContents().LocalName).Trim('\"');

            if (!string.IsNullOrEmpty(soapAction))
            {
                requestMessage.Headers.Action = soapAction;
            }

            var operation = _service.Operations.FirstOrDefault(o => o.SoapAction.Equals(soapAction, StringComparison.Ordinal) || o.Name.Equals(soapAction, StringComparison.Ordinal));

            if (operation == null)
            {
                throw new InvalidOperationException($"No operation found for specified action: {requestMessage.Headers.Action}");
            }
            _logger.LogInformation($"Request for operation {operation.Contract.Name}.{operation.Name} received");

            try
            {
                //Create an instance of the service class
                var serviceInstance = serviceProvider.GetService(_service.ServiceType);

                // Get operation arguments from message
                Dictionary <string, object> outArgs = new Dictionary <string, object>();
                var arguments = GetRequestArguments(requestMessage, operation, ref outArgs);
                var allArgs   = arguments.Concat(outArgs.Values).ToArray();

                // Invoke Operation method
                var responseObject = operation.DispatchMethod.Invoke(serviceInstance, allArgs);
                if (operation.DispatchMethod.ReturnType.IsConstructedGenericType && operation.DispatchMethod.ReturnType.GetGenericTypeDefinition() == typeof(Task <>))
                {
                    var   responseTask = (Task)responseObject;
                    await responseTask;
                    responseObject = responseTask.GetType().GetProperty("Result").GetValue(responseTask);
                }
                int i = arguments.Length;
                var resultOutDictionary = new Dictionary <string, object>();
                foreach (var outArg in outArgs)
                {
                    resultOutDictionary[outArg.Key] = allArgs[i];
                    i++;
                }

                // Create response message
                var resultName = operation.DispatchMethod.ReturnParameter.GetCustomAttribute <MessageParameterAttribute>()?.Name ?? operation.Name + "Result";
                var bodyWriter = new ServiceBodyWriter(_serializer, operation.Contract.Namespace, operation.Name + "Response", resultName, responseObject, resultOutDictionary);
                responseMessage = Message.CreateMessage(_messageEncoder.MessageVersion, null, bodyWriter);
                responseMessage = new CustomMessage(responseMessage);

                httpContext.Response.ContentType           = httpContext.Request.ContentType;       // _messageEncoder.ContentType;
                httpContext.Response.Headers["SOAPAction"] = responseMessage.Headers.Action;

                _messageEncoder.WriteMessage(responseMessage, httpContext.Response.Body);
            }
            catch (Exception exception)
            {
                _logger.LogWarning(0, exception, exception.Message);

                // Create response message
                while (exception.InnerException != null)
                {
                    exception = exception.InnerException;
                }

                var errorText = exception.Message;

                var transformer = serviceProvider.GetService <ExceptionTransformer>();
                if (transformer != null)
                {
                    errorText = transformer.Transform(exception.InnerException);
                }
                var bodyWriter = new FaultBodyWriter(new Fault {
                    FaultString = errorText
                });
                responseMessage = Message.CreateMessage(_messageEncoder.MessageVersion, null, bodyWriter);
                responseMessage = new CustomMessage(responseMessage);

                httpContext.Response.ContentType           = httpContext.Request.ContentType;       // _messageEncoder.ContentType;
                httpContext.Response.Headers["SOAPAction"] = responseMessage.Headers.Action;
                httpContext.Response.StatusCode            = StatusCodes.Status500InternalServerError;
                _messageEncoder.WriteMessage(responseMessage, httpContext.Response.Body);
            }

            return(responseMessage);
        }
        public async Task Invoke(HttpContext httpContext, IServiceProvider serviceProvider)
        {
            Console.WriteLine($"Request for {httpContext.Request.Path} received ({httpContext.Request.ContentLength ?? 0} bytes)");
            if (httpContext.Request.Path.Equals(_endpointPath, StringComparison.Ordinal))
            {
                Message responseMessage;

                // Read request message
                var requestMessage = _messageEncoder.ReadMessage(httpContext.Request.Body, 0x10000, httpContext.Request.ContentType);

                var soapAction = httpContext.Request.Headers["SOAPAction"].ToString().Trim('\"');
                if (!string.IsNullOrEmpty(soapAction))
                {
                    requestMessage.Headers.Action = soapAction;
                }

                var operation =
                    _service.Operations.FirstOrDefault(
                        o => o.SoapAction.Equals(requestMessage.Headers.Action, StringComparison.Ordinal));
                if (operation == null)
                {
                    throw new InvalidOperationException($"No operation found for specified action: {requestMessage.Headers.Action}");
                }
                // Get service type
                var serviceInstance = serviceProvider.GetService(_service.ServiceType);

                // Get operation arguments from message
                Dictionary <string, object> outArgs = new Dictionary <string, object>();
                var arguments = GetRequestArguments(requestMessage, operation, ref outArgs);
                var allArgs   = arguments.Concat(outArgs.Values).ToArray();
                // Invoke Operation method

                try
                {
                    var responseObject = operation.DispatchMethod.Invoke(serviceInstance, allArgs);
                    int i = arguments.Length;
                    var resultOutDictionary = new Dictionary <string, object>();
                    foreach (var outArg in outArgs)
                    {
                        resultOutDictionary[outArg.Key] = allArgs[i];
                        i++;
                    }

                    // Create response message
                    var resultName = operation.DispatchMethod.ReturnParameter.GetCustomAttribute <MessageParameterAttribute>()?.Name ?? operation.Name + "Result";
                    var bodyWriter = new ServiceBodyWriter(operation.Contract.Namespace, operation.Name + "Response", resultName, responseObject, resultOutDictionary);
                    responseMessage = Message.CreateMessage(_messageEncoder.MessageVersion, null, bodyWriter);
                    responseMessage = new CustomMessage(responseMessage);

                    httpContext.Response.ContentType           = httpContext.Request.ContentType;           // _messageEncoder.ContentType;
                    httpContext.Response.Headers["SOAPAction"] = responseMessage.Headers.Action;

                    _messageEncoder.WriteMessage(responseMessage, httpContext.Response.Body);
                }
                catch (Exception exception)
                {
                    // Create response message
                    var errorText   = exception.InnerException.Message;
                    var transformer = serviceProvider.GetService <ExceptionTransformer>();
                    if (transformer != null)
                    {
                        errorText = transformer.Transform(exception.InnerException);
                    }
                    var bodyWriter = new FaultBodyWriter(new Fault {
                        FaultString = errorText
                    });
                    responseMessage = Message.CreateMessage(_messageEncoder.MessageVersion, null, bodyWriter);
                    responseMessage = new CustomMessage(responseMessage);

                    httpContext.Response.ContentType           = httpContext.Request.ContentType;           // _messageEncoder.ContentType;
                    httpContext.Response.Headers["SOAPAction"] = responseMessage.Headers.Action;
                    httpContext.Response.StatusCode            = StatusCodes.Status500InternalServerError;
                    _messageEncoder.WriteMessage(responseMessage, httpContext.Response.Body);
                }
            }
            else
            {
                await _next(httpContext);
            }
        }