/// <summary> /// Calls service method which implements the X-Road operation. /// </summary> protected virtual void InvokeServiceMethod(XRoadContext context) { if (context.ServiceMap != null) { context.Result = InvokeMetaService(context); return; } context.ServiceMap = context.Request.GetSerializer().GetServiceMap(context.Request.RootElementName); context.Response.BinaryMode = context.ServiceMap.OperationDefinition.OutputBinaryMode; var serviceObject = GetServiceObject(context); DeserializeMethodInput(context); try { var parameters = context.ServiceMap.RequestDefinition.ParameterInfo != null ? new[] { context.Parameters } : new object[0]; context.Result = context.ServiceMap.OperationDefinition.MethodInfo.Invoke(serviceObject, parameters); } catch (Exception exception) { context.Exception = exception; OnInvocationError(context); if (context.Result == null) { throw; } } }
/// <summary> /// Handle incoming request. /// </summary> public virtual void ProcessRequest(HttpContext httpContext) { using (var context = new XRoadContext(httpContext)) { try { context.MessageFormatter = XRoadHelper.GetMessageFormatter(httpContext.Request.ContentType); httpContext.Request.InputStream.Position = 0; httpContext.Response.ContentType = XRoadHelper.GetContentTypeHeader(context.MessageFormatter.ContentType); HandleRequest(context); } catch (Exception exception) { if (context.MessageFormatter == null) { context.MessageFormatter = new SoapMessageFormatter(); } httpContext.Response.ContentType = XRoadHelper.GetContentTypeHeader(context.MessageFormatter.ContentType); if (httpContext.Response.OutputStream.CanSeek) { httpContext.Response.OutputStream.Seek(0, SeekOrigin.Begin); httpContext.Response.OutputStream.SetLength(0); } var fault = context.MessageFormatter.CreateFault(exception); OnExceptionOccurred(context, exception, fault); } } }
/// <summary> /// Deserializes X-Road request from SOAP message payload. /// </summary> protected virtual void DeserializeMethodInput(XRoadContext context) { var args = new BeforeDeserializationEventArgs(); OnBeforeDeserialization(context, args); context.Request.ContentStream.Position = 0; var reader = XmlReader.Create(context.Request.ContentStream, args.XmlReaderSettings); context.MessageFormatter.MoveToPayload(reader, context.Request.RootElementName); context.Parameters = context.ServiceMap.DeserializeRequest(reader, context.Request); OnAfterDeserialization(context); }
/// <summary> /// Serializes service result to a X-Road message response. /// </summary> protected virtual void SerializeXRoadResponse(XRoadContext context) { OnBeforeSerialization(context); context.Request.ContentStream.Position = 0; using (var reader = XmlReader.Create(context.Request.ContentStream, new XmlReaderSettings { CloseInput = false })) { var writer = new XmlTextWriter(context.Response.ContentStream, context.Response.ContentEncoding); writer.WriteStartDocument(); var protocolDefinition = context.Response.ServiceManager?.ProtocolDefinition; if (context.MessageFormatter.TryMoveToEnvelope(reader)) { context.MessageFormatter.WriteStartEnvelope(writer, reader.Prefix); writer.WriteAttributes(reader, true); writer.WriteMissingAttributes(protocolDefinition); } else { writer.WriteSoapEnvelope(context.MessageFormatter, protocolDefinition); } if (context.MessageFormatter.TryMoveToHeader(reader)) { writer.WriteNode(reader, true); } context.MessageFormatter.WriteStartBody(writer); if (context.MessageFormatter.TryMoveToBody(reader)) { writer.WriteAttributes(reader, true); } context.ServiceMap.SerializeResponse(writer, context.Result, context.Response, reader, CustomSerialization); writer.WriteEndDocument(); writer.Flush(); } context.Response.SaveTo(context.HttpContext, context.MessageFormatter); OnAfterSerialization(context); }
/// <inheritdoc /> protected override void HandleRequest(XRoadContext context) { if (context.HttpContext.Request.InputStream.Length == 0) { throw new InvalidQueryException("Empty request content"); } context.Request.LoadRequest(context.HttpContext, context.MessageFormatter, StoragePath.GetValueOrDefault(Path.GetTempPath()), serviceManagers); if (context.Request.ServiceManager == null && context.Request.MetaServiceMap == null) { var supportedProtocolsString = string.Join(", ", serviceManagers.Select(x => $@"""{x.Name}""")); throw new InvalidQueryException($"Could not detect X-Road message protocol version from request message. Adapter supports following protocol versions: {supportedProtocolsString}."); } context.Response.Copy(context.Request); context.ServiceMap = context.Request.MetaServiceMap; OnRequestLoaded(context); InvokeServiceMethod(context); SerializeXRoadResponse(context); }
/// <summary> /// Intercept X-Road service request handling after serialization of the response message. /// </summary> protected virtual void OnAfterSerialization(XRoadContext context) { }
/// <summary> /// Intercept X-Road service request handling before serialization of the response message. /// </summary> protected virtual void OnBeforeSerialization(XRoadContext context) { }
/// <summary> /// Customize XML reader settings before deserialization of the X-Road message. /// </summary> protected virtual void OnBeforeDeserialization(XRoadContext context, BeforeDeserializationEventArgs args) { }
/// <summary> /// Handle exception that occurred on service method invokation. /// </summary> protected virtual void OnInvocationError(XRoadContext context) { }
/// <summary> /// Intercept X-Road service request after request message is loaded. /// </summary> protected virtual void OnRequestLoaded(XRoadContext context) { }
/// <summary> /// Get main service object which implements the functionality of /// the operation. /// </summary> protected abstract object GetServiceObject(XRoadContext context);
/// <summary> /// Handle X-Road message protocol meta-service request. /// </summary> protected abstract object InvokeMetaService(XRoadContext context);
/// <summary> /// Handles all exceptions as technical SOAP faults. /// </summary> protected virtual void OnExceptionOccurred(XRoadContext context, Exception exception, IFault fault) { using (var writer = new XmlTextWriter(context.HttpContext.Response.OutputStream, XRoadEncoding.Utf8)) context.MessageFormatter.WriteSoapFault(writer, fault); }
/// <summary> /// Handle current X-Road operation. /// </summary> protected abstract void HandleRequest(XRoadContext context);