2using System.Collections;
3using System.Collections.Generic;
4using System.Diagnostics;
8using System.Net.Sockets;
19 public static partial class API
41 #region Explicit Get Methods
58 ValidateResourceId(
id);
79 ValidateResourceId(
id);
131 #endregion Explicit Get Methods
133 #region GET Resource Collection
184 #region Private Helper Methods
206 if (
baseType.ContainsGenericParameters)
223 .Where(
i =>
i.ContainsGenericParameters);
231 baseType.GetGenericArguments()[0].GetGenericParameterConstraints()[0]);
282 private static string DetermineCollectionNameAndBaseType(
295 "Could not resolve the collection name for this Resource, it must be " +
296 "provided manually via the 'collectionName' optional parameter.",
e);
305 #endregion Private Helper Methods
306 #endregion GET Resource Collection
308 #region Search Resource Collection
381 #endregion Search Resource Collection
383 #region Batch Requests
439 #endregion Batch Requests
441 #region Combined Request and Deserialization
492 #endregion Combined Request and Deserialization
494 #region Basic REST Request
536 request.ReadWriteTimeout =
request.Timeout;
578 "The initial request could not be completed due to a temporary " +
579 "communication error. Please reset the stream and try again. " +
580 "The error message was: " +
response.ErrorMessage);
592 "The request encountered what appears to be a temporary error, " +
594 "The final error message was: " +
response.ErrorMessage);
612 #endregion Basic REST Request
614 #region IRestResponse deserialization
626 () => Converter.Deserialize<
T>(
response));
642 #endregion IRestResponse deserialization
644 #region Private Helper Methods
645 #region Request Helpers
652 private static void PrepareRequestParameters(
659 if (!parameters.Any(p => p.Type ==
ParameterType.HttpHeader && p.Name.Equals(
"Authorization")))
662 request.AddHeader(
"Authorization",
$"Bearer {bearerToken.access_token}");
666 request.AddHeader(
"Authorization",
$"Basic {basicToken.access_token}");
675 throw new ArgumentException(
"More than one RequestBody parameter was supplied.");
688 Name = JSON_CONTENT_TYPE,
689 ContentType = JSON_CONTENT_TYPE,
691 Type = ParameterType.RequestBody
712 request.Parameters.AddRange(parameters);
714 #endregion Request Helpers
716 #region Response Helpers
730 h =>
h.Name.Equals(
"Location",
StringComparison.OrdinalIgnoreCase))?.Value?.ToString();
731 string message =
"The server returned a redirect status (" + response.StatusCode +
")";
732 Debug.WriteLine(message);
734 throw ServerErrorExceptionHelper(
response,
null,
null, message +
735 ", but did specify a redirect location.");
746 throw ServerErrorExceptionHelper(
response,
null,
null, message +
747 ", but wants to switch to a new host URL (" +
newUri.Host +
"). " +
748 "You will have to manually reconfigure your client to use this " +
749 "new address if you trust it.");
751 return newUri.AbsolutePath;
753 throw ServerErrorExceptionHelper(
response,
null,
null, message +
754 ", but the redirect location was not well formed: " +
newLocation);
791 Debug.WriteLine(
"WebException Occurred with Status: " +
792 $"{asWebException.Status}\n{asWebException}");
805 "connected party did not properly respond after a period of time, " +
806 "or established connection failed because connected host has failed to respond";
817 else if (
response.ErrorMessage.Contains(
"The operation has timed out"))
821 $"Server Communication Error - {response.ErrorMessage}");
834 string logPrefix =
$"The request timed out after {elapsed.TotalMilliseconds} ms";
840 Debug.WriteLine(
$"{logPrefix}, but the request object is empty. " +
841 "This likely indicates that a low-level timeout occurred before " +
842 "the response could be instantiated. The request will be retried.");
849 Debug.WriteLine(
$"{logPrefix}, but the configured timeout period " +
850 $"({response.Request.Timeout} ms) hasn't elapsed. " +
851 "This likely indicates a timeout occurred in the underlying TCP protocol. " +
852 "The request will be retried.");
857 Debug.WriteLine(
$"{logPrefix}. Re-raising the error returned (" +
858 $"{response.ErrorException.GetType().NiceTypeName()}) as a RequestTimeoutException.");
859 string message =
$"{logPrefix}. The requested timeout was {response.Request.Timeout} ms. " +
860 "If this is a large request, you may need to wait longer for a response. " +
861 "Check your API.DefaultRequestTimeout or set a timeout directly in your API call.";
903 Debug.WriteLine(
"The response was successfully parsed and returned.\n");
911 "The response could not be parsed into the desired type: \"" +
924 Debug.WriteLine(
"The following request failed:");
950 response.StatusCode != HttpStatusCode.ServiceUnavailable &&
957 if (String.IsNullOrWhiteSpace(
response.Content))
964 "The server response was an error but no error details were supplied.");
971 Debug.WriteLine(
"The response was received but contained a server error.");
988 Debug.WriteLine(
"The response was received but could not be parsed.");
994 #endregion Response Helpers
995 #endregion Private Helper Methods
Used to deserialize server OPTIONS response.
Describes a collection of resources which can be listed.
Used to deserialize server error messages.
Parameters that can be added to your REST requests to access additional API features.
static RequestParameters Ids(IEnumerable< string > ids)
Can be added to your collection GET requests to return only the set of resources whose id matches one...
static RequestParameters Search(string searchTerms)
Can be added to your GET requests to send a search request to the server. If the endpoint supports se...
static RequestParameters Page(long offset, long limit)
When getting a collection of items, these parameters can be added to restrict the number of results y...
static RequestParameters AdvancedSearch(string advancedSearchTerms)
Can be added to your GET requests to send a field filtering request to the server....
API methods / requests made available to the user.
static object GetUri(Type deserializeType, Uri href, IEnumerable< Parameter > requestParameters=null, int? timeout=null)
Perform a GET on an arbitrary resource by extracting the path and query parameters from a manually sp...
static OptionsResponse Options(IEnumerable< Parameter > requestParameters=null, int? timeout=null)
Perform an OPTIONS request on the API, which returns a list of features supported for the current aut...
static IAccessToken AuthenticationToken
The AccessToken storing authentication information for requests made to the server.
static int DefaultRequestTimeout
The default timeout used for all simple server requests, in milliseconds.
static volatile int MaxRequestRetries
When a temporary communication failure occurs (such as a socket error or an authentication failure fo...
static T RequestAndParse< T >(string resource, Method method, IEnumerable< Parameter > requestParameters=null, int? timeout=null)
Perform a REST request on the server and serializes the response to the desired compile-time type.
static T GetUri< T >(Uri href, IEnumerable< Parameter > requestParameters=null, int? timeout=null)
Perform a GET on an arbitrary resource by extracting the path and query parameters from a manually sp...
static string GetCollectionName< T >()
Gets the collection name for the given APIResource type, whether it's instantiable or not.
static ICollectionResponse< IAPIResource > GetResourceList(Type resourceType, IEnumerable< Parameter > requestParameters=null, string collectionNameOverride=null, int? timeout=null)
Get a collection of resources from the server.
static ICollectionResponse< T > BatchGet< T >(IEnumerable< string > ids, IEnumerable< Parameter > requestParameters=null, string collectionNameOverride=null, int? timeout=null)
Get a collection of resources from the server that match the set of resource ids specified.
static bool TryHandleAuthenticationErrors(IRestResponse response, int sequentialAttempts=0)
Checks an IRestResponse object for authentication errors, then invokes configured authentication dele...
static T ExtractRestResponse< T >(IRestResponse response)
Attempts to deserialize an IRestResponse content to the specified type T.
static int DefaultRequestTimeoutCollections
The default timeout used when requesting a resource collection from the server, in milliseconds.
static object ExtractRestResponse(IRestResponse response, Type deserializeType)
Attempts to deserialize an IRestResponse content to the specified run-time type.
static ICollectionResponse< IAPIResource > SearchResourceList(Type resourceType, string searchTerms, IEnumerable< Parameter > requestParameters=null, string collectionNameOverride=null, int? timeout=null, SearchType searchType=SearchType.Basic)
Get a collection of resources from the server that match the specified search criteria.
static object RequestAndParse(Type deserializeType, string resource, Method method, IEnumerable< Parameter > requestParameters=null, int? timeout=null)
Perform a REST request on the server and serializes the response to the desired run-time type.
static ICollectionResponse< T > SearchResourceList< T >(string searchTerms, IEnumerable< Parameter > requestParameters=null, string collectionNameOverride=null, int? timeout=null, SearchType searchType=SearchType.Basic)
Get a collection of resources from the server that match the specified search criteria.
static IAPIResource Get(Type resourceType, string id, IEnumerable< Parameter > requestParameters=null, int? timeout=null)
Get the selected resource by ID. The appropriate collection is automatically determined by the suppli...
SearchType
The search type determines the interpretation of the query string.
@ Basic
Search by keyword on predefined field.
@ Advanced
Search by complex query on key-value metadata. See Parameters.AdvancedSearch for details about advanc...
static string GetCollectionName(Type requestType)
Gets the collection name for the given APIResource type, whether it's instantiable or not.
static ICollectionResponse< IAPIResource > BatchGet(Type resourceType, IEnumerable< string > ids, IEnumerable< Parameter > requestParameters=null, string collectionNameOverride=null, int? timeout=null)
Get a collection of resources from the server that match the set of resource ids specified.
static IRestResponse ExecuteRestRequest(string resource, Method method, IEnumerable< Parameter > requestParameters=null, int? timeout=null, bool returnRawResponse=false, Action< Stream > responseStreamReader=null)
Perform a REST request on the server.
static T Get< T >(string id, IEnumerable< Parameter > requestParameters=null, int? timeout=null)
Get the selected resource by ID. The appropriate collection is automatically determined by the resour...
static ICollectionResponse< T > GetResourceList< T >(IEnumerable< Parameter > requestParameters=null, string collectionNameOverride=null, int? timeout=null)
Get a collection of resources from the server.
An AccessToken storing basic authentication information for requests made to the server.
An AccessToken storing Bearer authentication information for requests made to the server,...
Extends the TimeoutException class to contain the IRestResponse that timed out.
Helper class which makes it easier to build a set of request parameters.
Utility for resolving types given only the types name (Useful for parsing ambiguous JSON objects).
static Type GetGenericCovariantBase(Type T)
Returns the most strongly typed covariant base type which is assignable from the specified type T.
Interface for Base class used by all resources.