JsonHttpClient¶
JsonHttpClient is the sole public entry point of SAIF.Web.API.Clients. It wraps a RestSharp.RestClient to issue authenticated, retried, header-annotated HTTP calls against a SAIF JSON Web API, and routes every public verb method through one shared private funnel (GetJsonResponse) so authentication, identity headers, retry, and success-enforcement apply uniformly and cannot be bypassed per call. It has no base class, defines no interface, and has no virtual members, so it cannot be substituted or mocked without wrapping it.
Purpose¶
- Provide GET/POST/PUT/PATCH/DELETE verb methods (
GetResult<T>,GetResults<T>,GetResponse<T>,PostJson<T>,PutJson<T>,PatchJson<T>,DeleteJson<T>) that a consuming application uses to call a SAIF Web API without hand-writing HTTP, authentication, retry, or JSON-shape-normalization code (see Operations and processes). - Enforce BR-CLI-001, BR-CLI-002, BR-CLI-005, and BR-CLI-006 on every request via the shared
GetJsonResponsefunnel. - Translate transport-level responses into the
ApiResponse<T>envelope or a materializedT, normalizing array/object/scalar JSON shapes uniformly (BR-CLI-012).
Context¶
- Namespace:
SAIF.Web.API.Clients - Assembly/package:
SAIF.Web.API.Clients(NuGet packageSAIF.Web.API.Clients)
Public members¶
| Member | Signature | Purpose |
|---|---|---|
| Constructor | JsonHttpClient(Uri serviceBaseUri, ClientInfo clientInfo, IAuthenticator authenticator) |
Canonical constructor; falls back to new NtlmAuthenticator() when authenticator is null (BR-CLI-001). |
| Constructor | JsonHttpClient(Uri serviceBaseUri, ClientInfo clientInfo) |
Chains to the canonical constructor with new NtlmAuthenticator(). |
| Constructor | JsonHttpClient(Uri serviceBaseUri, ClientInfo clientInfo, IAuthenticator authenticator, int timeoutOverride) |
Chains to the canonical constructor, then sets TimeoutOverride. |
| Constructor | JsonHttpClient(Uri serviceBaseUri, ClientInfo clientInfo, int timeoutOverride) |
Chains to the canonical constructor with a fresh NtlmAuthenticator, then sets TimeoutOverride. This overload does not make a caller-supplied authenticator reachable, because it always passes a new NtlmAuthenticator*. |
TimeoutOverride |
int { get; } (ctor-assigned, default 0) |
Request timeout in milliseconds; applied only when greater than 0 (BR-CLI-010). |
DateTimeZoneHandling |
Newtonsoft.Json.DateTimeZoneHandling { get; set; } (default Local) |
Governs both request serialization and response deserialization of date values (BR-CLI-011). |
EnsureSuccessfulResponse |
bool { get; set; } (default true) |
When true, non-success responses are converted to typed exceptions instead of being returned to the caller (BR-CLI-006). |
SetOnBehalfOfUserHeaders |
bool { get; set; } (default false) |
When true, adds the OnBehalfOfUser header from the ambient HttpContext, requiring a web host (BR-CLI-003). |
RetryDelayInMs |
int { get; set; } (default 1000) |
Sleep duration between retry attempts. |
RetryOnStatusCodes |
IEnumerable<HttpStatusCode> { get; set; } (default {0, 502, 503, 401}) |
Status codes that trigger a retry before success is evaluated (BR-CLI-005). |
GetResult<T> |
T GetResult<T>(string methodUriSegment) |
Issues a GET and returns a single materialized T with type-specific coercion; see GetResult\<T>. |
GetResults<T> |
T[] GetResults<T>(string methodUriSegment) |
Issues a GET and returns ApiResponse<T>.Results; see GetResults\<T>. |
GetResponse<T> |
ApiResponse<T> GetResponse<T>(string methodUriSegment) |
Issues a GET and returns the full envelope; see GetResponse\<T>. |
PostJson<T> |
ApiResponse<T> PostJson<T>(string methodUriSegment, object requestBody) |
Issues a POST with a JSON body; see write operations. |
PutJson<T> |
ApiResponse<T> PutJson<T>(string methodUriSegment, object requestBody) |
Issues a PUT with a JSON body; see write operations. |
PatchJson<T> |
ApiResponse<T> PatchJson<T>(string methodUriSegment, object requestBody) |
Issues a PATCH with a JSON body; see write operations. |
DeleteJson<T> |
ApiResponse<T> DeleteJson<T>(string methodUriSegment, object requestBody) |
Issues a DELETE with a JSON body — there is no body-less DELETE overload; see write operations. |
Behavioral notes¶
- Every public verb method routes through the private
GetJsonResponsefunnel, so header injection, authentication, retry, and success-enforcement cannot be bypassed per call (GetJsonResponse). - All HTTP execution is synchronous and blocking (
client.Execute,Thread.Sleepfor retry delay); there is noasync/awaitsurface. - A new
RestClientis constructed for every call — there is no connection/handler reuse across calls*. SetOnBehalfOfUserHeaders = truecouples the client toSystem.Web.HttpContext.Current; calling it from a non-web host (console/service/test) throwsNullReferenceExceptionbecause no guard exists.GetContentArray<T>(internal static) normalizes JSON response shapes forGetResult<T>andGetResponse<T>, but is not part of the public surface; see GetContentArray\<T>.
Constraints and usage notes¶
ClientInfopassed to the constructor is not null-checked; anullvalue throwsNullReferenceExceptionwhen headers are added.methodUriSegment,serviceBaseUri, andrequestBodyreceive no input validation from this library.
Note: Statements marked with
*were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts.
Sources¶
src/SAIF.Web.API.Clients/JsonHttpClient.cs