Skip to content

Commit ba61f19

Browse files
committed
Merge branch 'hotfix/refactor_RestClient_BuildUri' of git://github.com/lsolano/RestSharp into lsolano-hotfix/refactor_RestClient_BuildUri
2 parents 48bef4d + 9df1f74 commit ba61f19

File tree

1 file changed

+108
-56
lines changed

1 file changed

+108
-56
lines changed

RestSharp/RestClient.cs

Lines changed: 108 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616

1717
#endregion
1818

19+
using RestSharp.Authenticators;
20+
using RestSharp.Deserializers;
21+
using RestSharp.Extensions;
1922
using System;
2023
using System.Collections.Generic;
2124
using System.Linq;
@@ -26,9 +29,6 @@
2629
using System.Security.Cryptography.X509Certificates;
2730
using System.Text;
2831
using System.Text.RegularExpressions;
29-
using RestSharp.Authenticators;
30-
using RestSharp.Deserializers;
31-
using RestSharp.Extensions;
3232

3333
namespace RestSharp
3434
{
@@ -255,65 +255,117 @@ public IRestResponse<T> Deserialize<T>(IRestResponse response)
255255
/// <param name="request">RestRequest to execute</param>
256256
/// <returns>Assembled System.Uri</returns>
257257
public Uri BuildUri(IRestRequest request)
258+
{
259+
DoBuildUriValidations(request);
260+
261+
KeyValuePair<string, string> tuple = ApplyUrlSegmentParamsValuesToBaseUriAndResource(request);
262+
263+
BaseUrl = new Uri(tuple.Key);
264+
string resource = tuple.Value;
265+
266+
string mergedUri = MergeBaseUrlAndResource(resource);
267+
268+
string finalUri = ApplyQueryStringParamsValuesToUri(mergedUri, request);
269+
270+
return new Uri(finalUri);
271+
}
272+
273+
private void DoBuildUriValidations(IRestRequest request)
258274
{
259275
if (BaseUrl == null)
276+
{
260277
throw new NullReferenceException("RestClient must contain a value for BaseUrl");
278+
}
279+
280+
IList<string> nullValuedParams = request.Parameters
281+
.Where(p => p.Type == ParameterType.UrlSegment && p.Value == null)
282+
.Select(p => p.Name)
283+
.ToList();
284+
285+
if (!nullValuedParams.Any())
286+
{
287+
return;
288+
}
289+
290+
string names = string.Join(", ", nullValuedParams.Select(name => $"'{name}'").ToArray());
291+
throw new ArgumentException($"Cannot build uri when url segment parameter(s) {names} value is null.", "request");
292+
}
261293

262-
var assembled = request.Resource;
263-
var urlParms = request.Parameters.Where(p => p.Type == ParameterType.UrlSegment);
294+
private KeyValuePair<string, string> ApplyUrlSegmentParamsValuesToBaseUriAndResource(IRestRequest request)
295+
{
296+
string assembled = request.Resource;
297+
bool hasResource = !string.IsNullOrEmpty(assembled);
298+
IEnumerable<Parameter> urlParms = request.Parameters.Where(p => p.Type == ParameterType.UrlSegment);
264299
var builder = new UriBuilder(BaseUrl);
265300

266-
foreach (var p in urlParms)
301+
foreach (Parameter parameter in urlParms)
267302
{
268-
if (p.Value == null)
269-
throw new ArgumentException(
270-
string.Format("Cannot build uri when url segment parameter '{0}' value is null.", p.Name),
271-
"request");
303+
string paramPlaceHolder = $"{{{parameter.Name}}}";
304+
string paramValue = parameter.Value.ToString().UrlEncode();
272305

273-
if (!string.IsNullOrEmpty(assembled))
274-
assembled = assembled.Replace("{" + p.Name + "}", p.Value.ToString().UrlEncode());
306+
if (hasResource)
307+
{
308+
assembled = assembled.Replace(paramPlaceHolder, paramValue);
309+
}
275310

276-
builder.Path = builder.Path.UrlDecode().Replace("{" + p.Name + "}", p.Value.ToString().UrlEncode());
311+
builder.Path = builder.Path.UrlDecode().Replace(paramPlaceHolder, paramValue);
277312
}
278313

279-
BaseUrl = new Uri(builder.ToString());
314+
return new KeyValuePair<string, string>(builder.ToString(), assembled);
315+
}
316+
317+
private string MergeBaseUrlAndResource(string resource)
318+
{
319+
string assembled = resource;
280320

281321
if (!string.IsNullOrEmpty(assembled) && assembled.StartsWith("/"))
322+
{
282323
assembled = assembled.Substring(1);
324+
}
283325

284-
if (BaseUrl != null && !string.IsNullOrEmpty(BaseUrl.AbsoluteUri))
326+
if (BaseUrl == null || string.IsNullOrEmpty(BaseUrl.AbsoluteUri))
285327
{
286-
var usingBaseUri = BaseUrl;
287-
if (!BaseUrl.AbsoluteUri.EndsWith("/") && !string.IsNullOrEmpty(assembled))
288-
usingBaseUri = new Uri(BaseUrl.AbsoluteUri + "/");
328+
return assembled;
329+
}
289330

290-
assembled = new Uri(usingBaseUri, assembled).AbsoluteUri;
331+
Uri usingBaseUri = BaseUrl;
332+
if (!BaseUrl.AbsoluteUri.EndsWith("/") && !string.IsNullOrEmpty(assembled))
333+
{
334+
usingBaseUri = new Uri(BaseUrl.AbsoluteUri + "/");
291335
}
292336

293-
IEnumerable<Parameter> parameters;
337+
assembled = new Uri(usingBaseUri, assembled).AbsoluteUri;
294338

295-
if (request.Method != Method.POST && request.Method != Method.PUT && request.Method != Method.PATCH)
296-
parameters = request.Parameters
297-
.Where(p => p.Type == ParameterType.GetOrPost ||
298-
p.Type == ParameterType.QueryString)
299-
.ToList();
300-
else
301-
parameters = request.Parameters
302-
.Where(p => p.Type == ParameterType.QueryString)
303-
.ToList();
339+
return assembled;
340+
}
341+
342+
private string ApplyQueryStringParamsValuesToUri(string mergedUri, IRestRequest request)
343+
{
344+
IList<Parameter> parameters = GetQueryStringParameters(request);
304345

305346
if (!parameters.Any())
306-
return new Uri(assembled);
347+
{
348+
return mergedUri;
349+
}
307350

308-
// build and attach querystring
309-
var data = EncodeParameters(parameters, Encoding);
310-
var separator = assembled != null && assembled.Contains("?")
311-
? "&"
312-
: "?";
351+
string separator = mergedUri != null && mergedUri.Contains("?") ? "&" : "?";
313352

314-
assembled = string.Concat(assembled, separator, data);
353+
return string.Concat(mergedUri, separator, EncodeParameters(parameters, Encoding));
354+
}
315355

316-
return new Uri(assembled);
356+
private static IList<Parameter> GetQueryStringParameters(IRestRequest request)
357+
{
358+
if (request.Method != Method.POST && request.Method != Method.PUT && request.Method != Method.PATCH)
359+
{
360+
return request.Parameters
361+
.Where(p => p.Type == ParameterType.GetOrPost ||
362+
p.Type == ParameterType.QueryString)
363+
.ToList();
364+
}
365+
366+
return request.Parameters
367+
.Where(p => p.Type == ParameterType.QueryString)
368+
.ToList();
317369
}
318370

319371
/// <summary>
@@ -445,34 +497,34 @@ private void ConfigureHttp(IRestRequest request, IHttp http)
445497
http.ConnectionGroupName = ConnectionGroupName;
446498

447499
var headers = from p in request.Parameters
448-
where p.Type == ParameterType.HttpHeader
449-
select new HttpHeader
450-
{
451-
Name = p.Name,
452-
Value = Convert.ToString(p.Value)
453-
};
500+
where p.Type == ParameterType.HttpHeader
501+
select new HttpHeader
502+
{
503+
Name = p.Name,
504+
Value = Convert.ToString(p.Value)
505+
};
454506

455507
foreach (var header in headers)
456508
http.Headers.Add(header);
457509

458510
var cookies = from p in request.Parameters
459-
where p.Type == ParameterType.Cookie
460-
select new HttpCookie
461-
{
462-
Name = p.Name,
463-
Value = Convert.ToString(p.Value)
464-
};
511+
where p.Type == ParameterType.Cookie
512+
select new HttpCookie
513+
{
514+
Name = p.Name,
515+
Value = Convert.ToString(p.Value)
516+
};
465517

466518
foreach (var cookie in cookies)
467519
http.Cookies.Add(cookie);
468520

469521
var @params = from p in request.Parameters
470-
where p.Type == ParameterType.GetOrPost && p.Value != null
471-
select new HttpParameter
472-
{
473-
Name = p.Name,
474-
Value = Convert.ToString(p.Value)
475-
};
522+
where p.Type == ParameterType.GetOrPost && p.Value != null
523+
select new HttpParameter
524+
{
525+
Name = p.Name,
526+
Value = Convert.ToString(p.Value)
527+
};
476528

477529
foreach (var parameter in @params)
478530
http.Parameters.Add(parameter);
@@ -632,4 +684,4 @@ private static bool IsWildcardStructuredSuffixSyntax(string contentType)
632684
return StructuredSyntaxSuffixWildcardRegex.IsMatch(contentType);
633685
}
634686
}
635-
}
687+
}

0 commit comments

Comments
 (0)