public async Task <(WebApiParameter[] inputParameters, OutputParameter[] outputParameters)> GetApiParameters(Filter.ParameterInterceptorContext context, IReadOnlyCollection <string> ignoreParameters, DbConnection dbConnection) { var method = context.Method; var spParamsRaw = await sPParametersProvider.GetSPParameters(method.SP, dbConnection); var spParams = ignoreParameters.Count == 0 ? spParamsRaw : spParamsRaw.Where(p => !ignoreParameters.Contains(p.SqlName.StartsWith("@") ? p.SqlName.Substring(1) : p.SqlName, StringComparer.OrdinalIgnoreCase)); var spPrmsNoCount = spParams.Where(p => p.ParameterDirection != System.Data.ParameterDirection.Output); var prmsOutRaw = spParams.Where(p => p.ParameterDirection == System.Data.ParameterDirection.Output || p.ParameterDirection == System.Data.ParameterDirection.InputOutput); var prmsOut = prmsOutRaw.Select(p => new OutputParameter(p.SqlName, p.DbType)).ToArray(); var webApiNames = namingMappingHandler.GetNames(spParams.Select(s => s.SqlName)).ToArray(); var userDefinedTypes = spParams.Where(u => u.UserDefinedType != null).Select(u => u.UserDefinedType !).Distinct(); Dictionary <DBObjectName, IReadOnlyCollection <SqlFieldDescription> > udtFields = new Dictionary <DBObjectName, IReadOnlyCollection <SqlFieldDescription> >(); foreach (var t in userDefinedTypes) { udtFields.Add(t, await sqlHelper.GetTableTypeFields(dbConnection, t)); } var apiParamsRaw = spParams.Select((s, index) => (WebApiParameter) new DbApiParameter(s.SqlName, webApiNames[index], s.DbType, s.IsNullable, s.UserDefinedType, s.UserDefinedType == null ? null: udtFields[s.UserDefinedType], namingMappingHandler) ); var apiParams = new LinkedList <WebApiParameter>(apiParamsRaw); foreach (var inter in parameterInterceptors) { inter.Intercept(apiParams, context); } return(apiParams.ToArray(), prmsOut); }
private async Task WriteOutputParameters(Stream outputStream, IReadOnlyCollection <DbParameter> outParameters) { Dictionary <string, object?> outParameterValues = outParameters.Cast <DbParameter>().ToDictionary( p => p.ParameterName.StartsWith("@") ? p.ParameterName.Substring(1) : p.ParameterName, p => p.Value); Kull.Data.DataReader.ObjectDataReader objectData = new Data.DataReader.ObjectDataReader( new IReadOnlyDictionary <string, object?>[] { outParameterValues } ); objectData.Read(); string[] fieldNames = new string[objectData.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] = objectData.GetName(i); } fieldNames = namingMappingHandler.GetNames(fieldNames).ToArray(); await WriteObject(outputStream, objectData, fieldNames); }
/// <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; } } }