-
-
Notifications
You must be signed in to change notification settings - Fork 731
/
RestService.cs
133 lines (110 loc) · 4.72 KB
/
RestService.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
using System;
using System.Net;
using System.Net.Http;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Threading;
using Newtonsoft.Json;
namespace Refit
{
interface IRestService
{
T For<T>(HttpClient client);
}
public static class RestService
{
public static T For<T>(HttpClient client, RefitSettings settings)
{
var className = "AutoGenerated" + typeof(T).Name;
var requestBuilder = RequestBuilder.ForType<T>(settings);
var typeName = typeof(T).AssemblyQualifiedName.Replace(typeof(T).Name, className);
var generatedType = Type.GetType(typeName);
if(generatedType == null) {
var message = typeof(T).Name + " doesn't look like a Refit interface. Make sure it has at least one " +
"method with a Refit HTTP method attribute and Refit is installed in the project.";
throw new InvalidOperationException(message);
}
return (T)Activator.CreateInstance(generatedType, client, requestBuilder);
}
public static T For<T>(HttpClient client)
{
return RestService.For<T>(client, null);
}
public static T For<T>(string hostUrl, RefitSettings settings)
{
#if PORTABLE
throw new NotImplementedException("You've somehow included the PCL version of Refit in your app. You need to use the platform-specific version!");
#else
// check to see if user provided custom auth t
HttpMessageHandler innerHandler = null;
if (settings != null) {
if (settings.HttpMessageHandlerFactory != null) {
innerHandler = settings.HttpMessageHandlerFactory();
}
if (settings.AuthorizationHeaderValueGetter != null) {
innerHandler = new AuthenticatedHttpClientHandler(settings.AuthorizationHeaderValueGetter, innerHandler);
}
}
var client = new HttpClient(innerHandler ?? new HttpClientHandler()) { BaseAddress = new Uri(hostUrl) };
return RestService.For<T>(client, settings);
#endif
}
public static T For<T>(string hostUrl)
{
return RestService.For<T>(hostUrl, null);
}
}
public class ApiException : Exception
{
public HttpStatusCode StatusCode { get; private set; }
public string ReasonPhrase { get; private set; }
public HttpResponseHeaders Headers { get; private set; }
public HttpMethod HttpMethod { get; private set; }
public Uri Uri { get; private set; }
public HttpContentHeaders ContentHeaders { get; private set; }
public string Content { get; private set; }
public bool HasContent
{
get { return !String.IsNullOrWhiteSpace(Content); }
}
public RefitSettings RefitSettings { get; set; }
ApiException(Uri uri, HttpMethod httpMethod, HttpStatusCode statusCode, string reasonPhrase, HttpResponseHeaders headers, RefitSettings refitSettings = null) :
base(createMessage(statusCode, reasonPhrase))
{
Uri = uri;
HttpMethod = httpMethod;
StatusCode = statusCode;
ReasonPhrase = reasonPhrase;
Headers = headers;
RefitSettings = refitSettings;
}
public T GetContentAs<T>()
{
return HasContent ?
JsonConvert.DeserializeObject<T>(Content, RefitSettings.JsonSerializerSettings) :
default(T);
}
public static async Task<ApiException> Create(Uri uri, HttpMethod httpMethod, HttpResponseMessage response, RefitSettings refitSettings = null)
{
var exception = new ApiException(uri, httpMethod, response.StatusCode, response.ReasonPhrase, response.Headers, refitSettings);
if (response.Content == null)
return exception;
try {
exception.ContentHeaders = response.Content.Headers;
exception.Content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
response.Content.Dispose();
} catch {
// NB: We're already handling an exception at this point,
// so we want to make sure we don't throw another one
// that hides the real error.
}
return exception;
}
static string createMessage(HttpStatusCode statusCode, string reasonPhrase)
{
return String.Format("Response status code does not indicate success: {0} ({1}).", (int)statusCode, reasonPhrase);
}
}
}