/// <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); }
/// <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); }
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); } }