-
Notifications
You must be signed in to change notification settings - Fork 395
/
Copy pathJsonHttpClient.cs
291 lines (252 loc) · 10.7 KB
/
JsonHttpClient.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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Salesforce.Common.Internals;
using Salesforce.Common.Models.Json;
using Salesforce.Common.Serializer;
namespace Salesforce.Common
{
public class JsonHttpClient : BaseHttpClient, IJsonHttpClient
{
private const string DateFormat = "s";
public JsonHttpClient(string instanceUrl, string apiVersion, string accessToken, HttpClient httpClient, bool callerWillDisposeHttpClient = false)
: base(instanceUrl, apiVersion, "application/json", httpClient, callerWillDisposeHttpClient)
{
HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
}
private static ForceException ParseForceException(string responseMessage)
{
var errorResponse = JsonConvert.DeserializeObject<ErrorResponses>(responseMessage);
return new ForceException(errorResponse[0].ErrorCode, errorResponse[0].Message);
}
// GET
public async Task<T> HttpGetAsync<T>(string urlSuffix)
{
var url = Common.FormatUrl(urlSuffix, InstanceUrl, ApiVersion);
return await HttpGetAsync<T>(url);
}
public async Task<T> HttpGetAsync<T>(Uri uri)
{
try
{
var response = await HttpGetAsync(uri);
var jToken = JToken.Parse(response);
if (jToken.Type == JTokenType.Array)
{
var jArray = JArray.Parse(response);
return JsonConvert.DeserializeObject<T>(jArray.ToString());
}
// else
try
{
var jObject = JObject.Parse(response);
return JsonConvert.DeserializeObject<T>(jObject.ToString());
}
catch
{
return JsonConvert.DeserializeObject<T>(response);
}
}
catch (BaseHttpClientException e)
{
throw ParseForceException(e.Message);
}
}
public async Task<IList<T>> HttpGetAsync<T>(string urlSuffix, string nodeName)
{
string next = null;
var records = new List<T>();
var url = Common.FormatUrl(urlSuffix, InstanceUrl, ApiVersion);
do
{
if (next != null)
{
url = Common.FormatUrl(string.Format("query/{0}", next.Split('/').Last()), InstanceUrl, ApiVersion);
}
try
{
var response = await HttpGetAsync(url);
var jObject = JObject.Parse(response);
var jToken = jObject.GetValue(nodeName);
next = (jObject.GetValue("nextRecordsUrl") != null) ? jObject.GetValue("nextRecordsUrl").ToString() : null;
records.AddRange(JsonConvert.DeserializeObject<IList<T>>(jToken.ToString()));
}
catch (BaseHttpClientException e)
{
throw ParseForceException(e.Message);
}
}
while (!string.IsNullOrEmpty(next));
return records;
}
public async Task<System.IO.Stream> HttpGetBlobAsync(string urlSuffix)
{
var url = Common.FormatUrl(urlSuffix, InstanceUrl, ApiVersion);
var request = new HttpRequestMessage
{
RequestUri = url,
Method = HttpMethod.Get
};
var responseMessage = await HttpClient.SendAsync(request).ConfigureAwait(false);
var response = await responseMessage.Content.ReadAsStreamAsync();
if (responseMessage.IsSuccessStatusCode)
{
return response;
}
else
{
return new System.IO.MemoryStream();
}
}
public async Task<T> HttpGetRestApiAsync<T>(string apiName)
{
var url = Common.FormatRestApiUrl(apiName, InstanceUrl);
return await HttpGetAsync<T>(url);
}
// POST
public async Task<T> HttpPostAsync<T>(object inputObject, string urlSuffix)
{
var url = Common.FormatUrl(urlSuffix, InstanceUrl, ApiVersion);
return await HttpPostAsync<T>(inputObject, url);
}
public async Task<T> HttpPostAsync<T>(object inputObject, Uri uri)
{
var json = JsonConvert.SerializeObject(inputObject,
Formatting.None,
new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
ContractResolver = new CreateableContractResolver(),
DateFormatString = DateFormat
});
try
{
var response = await HttpPostAsync(json, uri);
return JsonConvert.DeserializeObject<T>(response);
}
catch (BaseHttpClientException e)
{
throw ParseForceException(e.Message);
}
}
public async Task<T> HttpPostRestApiAsync<T>(string apiName, object inputObject)
{
var url = Common.FormatRestApiUrl(apiName, InstanceUrl);
return await HttpPostAsync<T>(inputObject, url);
}
public async Task<T> HttpBinaryDataPostAsync<T>(string urlSuffix, object inputObject, byte[] fileContents, string headerName, string fileName)
{
// BRAD: I think we should probably, in time, refactor multipart and binary support to the BaseHttpClient.
// For now though, I just left this in here.
var uri = Common.FormatUrl(urlSuffix, InstanceUrl, ApiVersion);
var json = JsonConvert.SerializeObject(inputObject,
Formatting.None,
new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
});
var content = new MultipartFormDataContent();
var stringContent = new StringContent(json, Encoding.UTF8, "application/json");
stringContent.Headers.Add("Content-Disposition", "form-data; name=\"json\"");
content.Add(stringContent);
var byteArrayContent = new ByteArrayContent(fileContents);
byteArrayContent.Headers.Add("Content-Type", "application/octet-stream");
byteArrayContent.Headers.Add("Content-Disposition", string.Format("form-data; name=\"{0}\"; filename=\"{1}\"", headerName, fileName));
content.Add(byteArrayContent, headerName, fileName);
var responseMessage = await HttpClient.PostAsync(uri, content).ConfigureAwait(false);
var response = await responseMessage.Content.ReadAsStringAsync().ConfigureAwait(false);
if (responseMessage.IsSuccessStatusCode)
{
return JsonConvert.DeserializeObject<T>(response);
}
throw ParseForceException(response);
}
// PATCH
public async Task<SuccessResponse> HttpPatchAsync(object inputObject, string urlSuffix, IDictionary<string, string> headers = default)
{
var url = Common.FormatUrl(urlSuffix, InstanceUrl, ApiVersion);
return await HttpPatchAsync(inputObject, url, headers);
}
public async Task<SuccessResponse> HttpPatchAsync(object inputObject, string urlSuffix, bool ignoreNull, IDictionary<string, string> headers = default)
{
var url = Common.FormatUrl(urlSuffix, InstanceUrl, ApiVersion);
if (ignoreNull == true)
{
return await HttpPatchAsync(inputObject, url, headers);
}
else
{
return await HttpPatchAsync(inputObject, url, NullValueHandling.Include, headers);
}
// return await HttpPatchAsync(inputObject, url, ignoreNull, headers);
}
public async Task<SuccessResponse> HttpPatchAsync(object inputObject, Uri uri, IDictionary<string, string> headers = default)
{
var json = JsonConvert.SerializeObject(inputObject,
Formatting.None,
new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
ContractResolver = new UpdateableContractResolver(),
DateFormatString = DateFormat
});
try
{
var response = await base.HttpPatchAsync(json, uri, headers);
return string.IsNullOrEmpty(response) ?
new SuccessResponse{ Id = "", Errors = "", Success = true } :
JsonConvert.DeserializeObject<SuccessResponse>(response);
}
catch (BaseHttpClientException e)
{
throw ParseForceException(e.Message);
}
}
public async Task<SuccessResponse> HttpPatchAsync(object inputObject, Uri uri, NullValueHandling nullValueHandling, IDictionary<string, string> headers = default)
{
var json = JsonConvert.SerializeObject(inputObject,
Formatting.None,
new JsonSerializerSettings
{
NullValueHandling = nullValueHandling,
ContractResolver = new UpdateableContractResolver(),
DateFormatString = DateFormat
});
try
{
var response = await base.HttpPatchAsync(json, uri, headers);
return string.IsNullOrEmpty(response) ?
new SuccessResponse { Id = "", Errors = "", Success = true } :
JsonConvert.DeserializeObject<SuccessResponse>(response);
}
catch (BaseHttpClientException e)
{
throw ParseForceException(e.Message);
}
}
// DELETE
public async Task<bool> HttpDeleteAsync(string urlSuffix)
{
var url = Common.FormatUrl(urlSuffix, InstanceUrl, ApiVersion);
return await HttpDeleteAsync(url);
}
public new async Task<bool> HttpDeleteAsync(Uri uri)
{
try
{
await base.HttpDeleteAsync(uri);
return true;
}
catch (BaseHttpClientException e)
{
throw ParseForceException(e.Message);
}
}
}
}