public Task HandleRequest(HttpContext context, Entity ent)
        {
#if NET48
            var method = ent.GetMethod(context.Request.HttpMethod);
#else
            var method = ent.GetMethod(context.Request.Method);
#endif
            foreach (var interceptor in this.requestInterceptors)
            {
                var shouldIntercept = interceptor.OnBeforeRequest(context, new RequestInterceptorContext(
                                                                      ent, method, this.dbConnection));
                if (shouldIntercept != null)
                {
                    context.Response.StatusCode = shouldIntercept.Value.statusCode;
                    return(HttpHandlingUtils.HttpContentToResponse(shouldIntercept.Value.responseContent, context.Response));
                }
            }
#if NET48
            var accept = (context.Request.Headers["Accept"] ?? "").Split(',').Select(ac => MediaTypeHeaderValue.Parse(ac)).ToList();
#else
            var accept = context.Request.GetTypedHeaders().Accept;
#endif
            IGenericSPSerializer?serializer = serializerResolver.GetSerialializerOrNull(accept,
                                                                                        ent, method);
            if (serializer == null)
            {
                context.Response.StatusCode = 415;
                return(Task.CompletedTask);
            }
            if (this.sPMiddlewareOptions.RequireAuthenticated && context.User?.Identity == null)
            {
                context.Response.StatusCode = 401;
                return(Task.CompletedTask);
            }
#if NET48
            if (context.Request.HttpMethod.ToUpper() == "GET")
#else
            if (context.Request.Method.ToUpper() == "GET")
#endif
            {
                return(HandleGetRequest(context, ent, serializer));
            }
            return(HandleBodyRequest(context, method, ent, serializer));
        }
示例#2
0
        /// <summary>
        /// Writes the result data to the body
        /// </summary>
        /// <param name="context">The HttpContext</param>
        /// <param name="cmd">The Db Command</param>
        /// <param name="method">The Http/SP mapping</param>
        /// <param name="ent">The Entity mapping</param>
        /// <returns>A Task</returns>
        public async Task ReadResultToBody(SerializationContext serializationContext)
        {
            var  context = serializationContext.HttpContext;
            var  method  = serializationContext.Method;
            var  ent     = serializationContext.Entity;
            bool html    = IsHtmlRequest(context);

#if !NETSTD2 && !NETFX
            var syncIOFeature = context.Features.Get <Microsoft.AspNetCore.Http.Features.IHttpBodyControlFeature>();
            if (syncIOFeature != null)
            {
                syncIOFeature.AllowSynchronousIO = true;
            }
#endif
            try
            {
                using (var rdr = await serializationContext.ExecuteReaderAsync())
                {
                    bool firstRead = rdr.Read();
                    await PrepareHeader(context, method, ent, 200);

#if NET48
                    using (var xmlWriter = new System.Xml.XmlTextWriter(context.Response.OutputStream, options.Encoding))
#else
                    using (var xmlWriter = new System.Xml.XmlTextWriter(context.Response.Body, options.Encoding))
#endif
                    {
                        string[] fieldNames = new string[rdr.FieldCount];
                        for (int i = 0; i < fieldNames.Length; i++)
                        {
                            fieldNames[i] = rdr.GetName(i);
                        }
                        fieldNames = namingMappingHandler.GetNames(fieldNames).ToArray();

                        xmlWriter.WriteStartElement("table");
                        {
                            if (html)
                            {
                                xmlWriter.WriteStartElement("thead");
                                {
                                    xmlWriter.WriteStartElement("tr");
                                    foreach (var field in fieldNames)
                                    {
                                        xmlWriter.WriteStartElement("th");
                                        xmlWriter.WriteValue(field);
                                        xmlWriter.WriteEndElement();
                                    }
                                    xmlWriter.WriteEndElement();
                                }
                                xmlWriter.WriteEndElement();//thead
                                xmlWriter.WriteStartElement("tbody");
                            }
                            while (firstRead || rdr.Read())
                            {
                                firstRead = false;
                                xmlWriter.WriteStartElement("tr");
                                for (int p = 0; p < fieldNames.Length; p++)
                                {
                                    xmlWriter.WriteStartElement(html ? "td" : fieldNames[p]);
                                    object vl = rdr.GetValue(p);
                                    xmlWriter.WriteValue(vl == DBNull.Value ? null : vl);
                                    xmlWriter.WriteEndElement();
                                }
                                xmlWriter.WriteEndElement();
                            }
                            if (html)
                            {
                                xmlWriter.WriteEndElement();
                            }
                        }
                        xmlWriter.WriteEndElement();
                    }
                }
            }
            catch (Exception err)
            {
                bool handled = false;
                foreach (var hand in errorHandlers)
                {
                    var result = hand.GetContent(err, o =>
                    {
                        var ser = new System.Xml.Serialization.XmlSerializer(o.GetType());
                        string xml;
                        using (var strW = new System.IO.StringWriter())
                        {
                            ser.Serialize(strW, o);
                            xml = strW.ToString();
                        }
                        var content = new System.Net.Http.StringContent(xml);
                        content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/xml");
                        return(content);
                    });
                    if (result != null)
                    {
                        (var status, var content) = result.Value;
#if NET48
                        if (!context.Response.HeadersWritten)
#else
                        if (!context.Response.HasStarted)
#endif
                        {
                            await PrepareHeader(context, method, ent, status);

                            await HttpHandlingUtils.HttpContentToResponse(content, context.Response).ConfigureAwait(false);
                        }
                        else
                        {
                            logger.LogError(err, $"Could not execute {serializationContext} and could not handle error");
                        }
                        handled = true;
                        break;
                    }
                }
                if (!handled)
                {
                    throw;
                }
            }
        }
        /// <summary>
        /// Writes the result data to the body
        /// </summary>
        /// <param name="context">The HttpContext</param>
        /// <param name="cmd">The Db Command</param>
        /// <param name="method">The Http/SP mapping</param>
        /// <param name="ent">The Entity mapping</param>
        /// <returns>A Task</returns>
        public async Task ReadResultToBody(SerializationContext serializationContext)
        {
            var context = serializationContext.HttpContext;
            var method  = serializationContext.Method;
            var ent     = serializationContext.Entity;

            try
            {
                using (var rdr = await serializationContext.ExecuteReaderAsync())
                {
                    bool firstRead = rdr.Read();
                    if (!firstRead)
                    {
                        await PrepareHeader(context, method, ent, 404, "application/json", null);

                        return;
                    }
                    byte[] content     = (byte[])rdr.GetValue(rdr.GetOrdinal(ContentColumn));
                    string?fileName    = rdr.GetNString(FileNameColumn);
                    string contentType = rdr.GetNString(ContentTypeColumn) ?? DefaultContentType;

                    await PrepareHeader(context, method, ent, 200, contentType, fileName);

#if NETFX
                    await context.Response.OutputStream.WriteAsync(content, 0, content.Length);
#else
                    await context.Response.Body.WriteAsync(content, 0, content.Length);
#endif
                }
            }
            catch (Exception err)
            {
                bool handled = false;
                foreach (var hand in errorHandlers)
                {
                    var result = hand.GetContent(err, o =>
                    {
                        string json = Newtonsoft.Json.JsonConvert.SerializeObject(o);
                        var content = new System.Net.Http.StringContent(json);
                        content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
                        return(content);
                    });
                    if (result != null)
                    {
                        (var status, var content) = result.Value;
#if NETFX
                        if (!context.Response.HeadersWritten)
#else
                        if (!context.Response.HasStarted)
#endif
                        {
                            await PrepareHeader(context, method, ent, status, "application/json", null);

                            await HttpHandlingUtils.HttpContentToResponse(content, context.Response).ConfigureAwait(false);
                        }
                        else
                        {
                            logger.LogError(err, $"Could not execute {serializationContext} and could not handle error");
                        }
                        handled = true;
                        break;
                    }
                }
                if (!handled)
                {
                    throw;
                }
            }
        }
        /// <summary>
        /// Writes the result data to the body
        /// </summary>
        /// <param name="context">The HttpContext</param>
        /// <param name="cmd">The Db Command</param>
        /// <param name="method">The Http/SP mapping</param>
        /// <param name="ent">The Entity mapping</param>
        /// <returns>A Task</returns>
        public async Task ReadResultToBody(SerializationContext serializationContext)
        {
            var context       = serializationContext.HttpContext;
            var method        = serializationContext.Method;
            var ent           = serializationContext.Entity;
            var outParameters = serializationContext.GetParameters()
                                .Where(p => p.Direction == System.Data.ParameterDirection.Output || p.Direction == System.Data.ParameterDirection.InputOutput)
                                .ToArray();
            bool wrap = options.AlwaysWrapJson || outParameters.Length > 0;

            try
            {
                using (var rdr = await serializationContext.ExecuteReaderAsync())
                {
                    bool firstReadResult = rdr.Read();
                    await PrepareHeader(context, method, ent, 200);


                    string[] fieldNames = new string[rdr.FieldCount];

                    // Will store the types of the fields. Nullable datatypes will map to normal types
                    for (int i = 0; i < fieldNames.Length; i++)
                    {
                        fieldNames[i] = rdr.GetName(i);
                    }
                    fieldNames = namingMappingHandler.GetNames(fieldNames).ToArray();
#if NETFX
                    var stream = context.Response.OutputStream;;
#else
                    var stream = context.Response.Body;
#endif
                    if (wrap)
                    {
                        await WriteRaw(stream, $"{{ \"{codeConvention.FirstResultKey}\": \r\n");

                        await WriteCurrentResultSet(stream, rdr, fieldNames, firstReadResult);

                        bool first         = true;
                        bool hasAnyResults = false;
                        while (await rdr.NextResultAsync())
                        {
                            if (first)
                            {
                                await WriteRaw(stream, $", \"{codeConvention.OtherResultsKey}\": [");

                                first         = false;
                                hasAnyResults = true;
                            }
                            else
                            {
                                await WriteRaw(stream, ",");
                            }
                            await WriteCurrentResultSet(stream, rdr, fieldNames, false);
                        }
                        if (hasAnyResults)
                        {
                            await WriteRaw(stream, "]");
                        }
                        if (outParameters.Length > 0)
                        {
                            await WriteRaw(stream, $", \"{codeConvention.OutputParametersKey}\": ");
                            await WriteOutputParameters(stream, outParameters);
                        }
                        await WriteRaw(stream, "\r\n}");
                    }
                    else
                    {
                        await WriteCurrentResultSet(stream, rdr, fieldNames, firstReadResult);
                    }
                    await stream.FlushAsync();

#if NET48
                    await context.Response.FlushAsync();
#endif
                }
            }
            catch (Exception err)
            {
#if NETFX
                logger.LogWarning($"Error executing {serializationContext} {err}");
#else
                logger.LogWarning(err, $"Error executing {serializationContext}");
#endif
                bool handled = false;
                foreach (var hand in errorHandlers)
                {
                    var result = hand.GetContent(err, o =>
                    {
                        string json = Newtonsoft.Json.JsonConvert.SerializeObject(o);
                        var content = new System.Net.Http.StringContent(json);
                        content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
                        return(content);
                    });
                    if (result != null)
                    {
                        (var status, var content) = result.Value;
#if NETFX
                        if (!context.Response.HeadersWritten)
#else
                        if (!context.Response.HasStarted)
#endif
                        {
                            await PrepareHeader(context, method, ent, status);

                            await HttpHandlingUtils.HttpContentToResponse(content, context.Response).ConfigureAwait(false);
                        }
                        else
                        {
                            logger.LogError(err, $"Could not execute {serializationContext} and could not handle error");
                        }
                        handled = true;
                        break;
                    }
                }
                if (!handled)
                {
                    throw;
                }
            }
        }