-
Notifications
You must be signed in to change notification settings - Fork 50
/
Copy pathWebApiExtensions.parameters.cs
179 lines (142 loc) · 7.44 KB
/
WebApiExtensions.parameters.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
// Copyright (c) 2015 Abel Cheng <abelcys@gmail.com> and other contributors.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
// Repository: https://github.com/DataBooster/DbWebApi
using System;
using System.Linq;
using System.Net.Http;
using System.Collections.Generic;
using Newtonsoft.Json;
namespace DataBooster.DbWebApi
{
public static partial class WebApiExtensions
{
#region QueryString Utilities
public static IDictionary<string, object> GetQueryStringDictionary(this HttpRequestMessage request)
{
if (request == null)
return null;
IDictionary<string, object> queryStrings;
if (_QueryStringCache.TryGetValue(request.RequestUri, out queryStrings))
return queryStrings;
queryStrings = request.GetQueryNameValuePairs().NameValuePairsToDictionary();
if (queryStrings == null)
return new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
_QueryStringCache.TryAdd(request.RequestUri, queryStrings);
return queryStrings;
}
internal static IDictionary<string, object> NameValuePairsToDictionary<T>(this IEnumerable<KeyValuePair<string, T>> nameValuePairs)
{
if (nameValuePairs == null)
return null;
else
return nameValuePairs.GroupBy(n => n.Key.Trim(), v => v.Value, StringComparer.OrdinalIgnoreCase).Where(n => n.Key.Length > 0)
.ToDictionary(k => k.Key, v => (v.Count() == 1) ? (object)v.First() : (object)v.ToArray(), StringComparer.OrdinalIgnoreCase);
}
internal static string GetQueryFileName(this IDictionary<string, object> queryStrings, string queryName, string filenameExtension)
{
string queryFileName = queryStrings.GetQueryParameterValue(queryName);
if (!string.IsNullOrEmpty(queryFileName))
{
if (queryFileName[0] == '.' || queryFileName[0] == '"')
queryFileName = queryFileName.TrimStart('.', '"');
if (queryFileName.Length > 0 && queryFileName[queryFileName.Length - 1] == '"')
queryFileName = queryFileName.TrimEnd('"');
if (queryFileName.Length > 0)
{
int dotPos = queryFileName.LastIndexOf('.');
if (dotPos < 0)
return queryFileName + '.' + filenameExtension;
if (dotPos > 0)
if (dotPos == queryFileName.Length - 1)
return queryFileName + filenameExtension;
else
return queryFileName;
}
}
return "[save_as]." + filenameExtension;
}
internal static string GetQueryParameterValue(this IDictionary<string, object> queryStringDictionary, string parameterName)
{
if (queryStringDictionary == null || queryStringDictionary.Count == 0 || string.IsNullOrEmpty(parameterName))
return null;
string prefix = DbWebApiOptions.QueryStringContract.ReservedParameterPrefix;
object parameterValue;
if (prefix.Length > 0)
if (queryStringDictionary.TryGetValue(prefix + parameterName, out parameterValue))
return GetFirstStringFromObject(parameterValue);
if (queryStringDictionary.TryGetValue(parameterName, out parameterValue))
return GetFirstStringFromObject(parameterValue);
else
return null;
}
private static string GetFirstStringFromObject(object oValue)
{
if (oValue == null)
return null;
string strValue = oValue as string;
if (strValue != null)
return strValue;
string[] strValues = oValue as string[];
if (strValues != null)
if (strValues.Length > 0)
return strValues[0];
else
return null;
return oValue.ToString();
}
#endregion
/// <summary>
/// <para>Gather required parameters of database stored procedure/function from body and from uri query string.</para>
/// <para>1. From body is the first priority, the input parameters will be gathered from body if the request has a message body;</para>
/// <para>2. Suppose all required input parameters were encapsulated as a JSON string into a special query string named "JsonInput";</para>
/// <para>3. Any query string which name matched with stored procedure input parameter' name will be forwarded to database.</para>
/// </summary>
/// <param name="request">The HTTP request. This is an extension method to HttpRequestMessage, when you use instance method syntax to call this method, omit this parameter.</param>
/// <param name="parametersFromBody">The parameters read from body.</param>
/// <returns>Final input parameters dictionary (name-value pairs) to pass to database call.</returns>
public static IDictionary<string, object> GatherInputParameters(this HttpRequestMessage request, IDictionary<string, object> parametersFromBody)
{
return GatherInputParameters(request, parametersFromBody, DbWebApiOptions.QueryStringContract.JsonInputParameterName);
}
/// <summary>
/// <para>Gather required parameters of database stored procedure/function from body and from uri query string.</para>
/// <para>1. From body is the first priority, the input parameters will be gathered from body if the request has a message body;</para>
/// <para>2. Suppose all required input parameters were encapsulated as a JSON string into a special query string named "JsonInput";</para>
/// <para>3. Any query string which name matched with stored procedure input parameter' name will be forwarded to database.</para>
/// </summary>
/// <param name="request">The HTTP request. This is an extension method to HttpRequestMessage, when you use instance method syntax to call this method, omit this parameter.</param>
/// <param name="parametersFromBody">The parameters read from body.</param>
/// <param name="jsonInput">The special pre-arranged name in query string. Default as JsonInput.</param>
/// <returns>Final input parameters dictionary (name-value pairs) to pass to database call.</returns>
public static IDictionary<string, object> GatherInputParameters(this HttpRequestMessage request, IDictionary<string, object> parametersFromBody, string jsonInput)
{
IDictionary<string, object> queryStringDictionary = request.GetQueryStringDictionary();
string jsonInputString = queryStringDictionary.GetQueryParameterValue(jsonInput);
if (!string.IsNullOrWhiteSpace(jsonInputString))
queryStringDictionary = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonInputString);
if (parametersFromBody == null)
return queryStringDictionary;
if (queryStringDictionary == null)
return parametersFromBody;
foreach (KeyValuePair<string, object> fromUri in queryStringDictionary)
if (!parametersFromBody.ContainsKey(fromUri.Key))
parametersFromBody.Add(fromUri); // As a supplement
return parametersFromBody;
}
public static void BulkGatherInputParameters<T>(this HttpRequestMessage request, IList<T> bulkParameterSetsFromBody, string jsonInput) where T : IDictionary<string, object>
{
if (bulkParameterSetsFromBody == null || bulkParameterSetsFromBody.Count == 0)
return;
IDictionary<string, object> fixedParametersFromUri = GatherInputParameters(request, null, jsonInput);
if (fixedParametersFromUri != null && fixedParametersFromUri.Count > 0)
foreach (IDictionary<string, object> batch in bulkParameterSetsFromBody)
foreach (KeyValuePair<string, object> fromUri in fixedParametersFromUri)
if (!batch.ContainsKey(fromUri.Key))
batch.Add(fromUri); // As a supplement
}
public static void BulkGatherInputParameters<T>(this HttpRequestMessage request, IList<T> bulkParameterSetsFromBody) where T : IDictionary<string, object>
{
BulkGatherInputParameters(request, bulkParameterSetsFromBody, DbWebApiOptions.QueryStringContract.JsonInputParameterName);
}
}
}