- Notifications
You must be signed in to change notification settings - Fork 51
/
Copy pathResponseHandler.cs
86 lines (79 loc) · 4.93 KB
/
ResponseHandler.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
// ------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information.
// ------------------------------------------------------------------------------
namespaceMicrosoft.Graph
{
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Net.Http;
usingSystem.Threading.Tasks;
usingMicrosoft.Kiota.Abstractions;
usingMicrosoft.Kiota.Abstractions.Serialization;
/// <summary>
/// Provides method(s) to deserialize raw HTTP responses into strong types.
/// </summary>
publicclassResponseHandler<T>:IResponseHandlerwhereT:IParsable,new()
{
privatereadonlyIAsyncParseNodeFactory_jsonParseNodeFactory;
/// <summary>
/// Constructs a new <see cref="ResponseHandler{T}"/>.
/// </summary>
/// <param name="parseNodeFactory"> The <see cref="IParseNodeFactory"/> to use for response handling</param>
publicResponseHandler(IParseNodeFactoryparseNodeFactory=null)
{
_jsonParseNodeFactory=parseNodeFactoryasIAsyncParseNodeFactory??ParseNodeFactoryRegistry.DefaultInstance;;
}
/// <summary>
/// Process raw HTTP response into requested domain type.
/// </summary>
/// <typeparam name="NativeResponseType">The type of the response</typeparam>
/// <typeparam name="ModelType">The type to return</typeparam>
/// <param name="response">The HttpResponseMessage to handle</param>
/// <param name="errorMappings">The errorMappings to use in the event of failed requests</param>
/// <returns></returns>
publicasyncTask<ModelType>HandleResponseAsync<NativeResponseType,ModelType>(NativeResponseTyperesponse,Dictionary<string,ParsableFactory<IParsable>>errorMappings)
{
if(responseisHttpResponseMessageresponseMessage&&responseMessage.Content!=null&&typeof(T).IsAssignableFrom(typeof(ModelType)))
{
awaitValidateSuccessfulResponseAsync(responseMessage,errorMappings).ConfigureAwait(false);
usingvarresponseStream=awaitresponseMessage.Content.ReadAsStreamAsync().ConfigureAwait(false);
varjsonParseNode=await_jsonParseNodeFactory.GetRootParseNodeAsync(responseMessage.Content.Headers?.ContentType?.MediaType?.ToLowerInvariant(),responseStream);
return(ModelType)(object)jsonParseNode.GetObjectValue<T>((parsable)=>newT());
}
returndefault;
}
/// <summary>
/// Validates the HttpResponse message is a successful response. Otherwise, throws a ServiceException with the error information
/// present in the response body.
/// </summary>
/// <param name="httpResponseMessage">The <see cref="HttpResponseMessage"/> to validate</param>
/// <param name="errorMapping">The errorMappings to use in the event of failed requests</param>
privateasyncTaskValidateSuccessfulResponseAsync(HttpResponseMessagehttpResponseMessage,Dictionary<string,ParsableFactory<IParsable>>errorMapping)
{
if(httpResponseMessage.IsSuccessStatusCode)
return;
varstatusCodeAsInt=(int)httpResponseMessage.StatusCode;
varstatusCodeAsString=statusCodeAsInt.ToString();
usingvarresponseStream=awaithttpResponseMessage.Content.ReadAsStreamAsync().ConfigureAwait(false);
varrootNode=await_jsonParseNodeFactory.GetRootParseNodeAsync(httpResponseMessage.Content.Headers?.ContentType?.MediaType?.ToLowerInvariant(),responseStream);
ParsableFactory<IParsable>errorFactory;
if(errorMapping==null||
!errorMapping.TryGetValue(statusCodeAsString,outerrorFactory)&&
!(statusCodeAsInt>=400&&statusCodeAsInt<500&&errorMapping.TryGetValue("4XX",outerrorFactory))&&
!(statusCodeAsInt>=500&&statusCodeAsInt<600&&errorMapping.TryGetValue("5XX",outerrorFactory)))
{
// We don't have an error mapping available to match. So default to using the odata specification
thrownewServiceException(ErrorConstants.Codes.GeneralException,httpResponseMessage.Headers,(int)httpResponseMessage.StatusCode,awaithttpResponseMessage.Content.ReadAsStringAsync().ConfigureAwait(false));
}
else
{
// Use the errorFactory to create an error response
varresult=rootNode.GetObjectValue(errorFactory);
if(resultis not Exceptionex)
thrownewApiException($"The server returned an unexpected status code and the error registered for this code failed to deserialize: {statusCodeAsString}");
else
throwex;
}
}
}
}