-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
externalservicehandler refactored totally. blacklist by url/pageurl d…
…one. issue #66 resolved
- Loading branch information
1 parent
fe27835
commit 0f54cd7
Showing
18 changed files
with
954 additions
and
381 deletions.
There are no files selected for viewing
236 changes: 93 additions & 143 deletions
236
...ers/Jinget.Handlers.ExternalServiceHandlers/DefaultServiceHandler/JingetServiceHandler.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,153 +1,103 @@ | ||
using Jinget.Core.ExtensionMethods; | ||
namespace Jinget.Handlers.ExternalServiceHandlers.DefaultServiceHandler; | ||
|
||
namespace Jinget.Handlers.ExternalServiceHandlers.DefaultServiceHandler; | ||
|
||
public class JingetServiceHandler<TResponseModel> : ServiceHandler<JingetServiceHandlerEvents<TResponseModel>> where TResponseModel : class, new() | ||
/// <summary> | ||
/// Service handler for processing HTTP responses with a specific response model. | ||
/// </summary> | ||
/// <typeparam name="TResponseModel">The type of the response model.</typeparam> | ||
public class JingetServiceHandler<TResponseModel> : JingetServiceHandlerBase<JingetServiceHandlerEvents<TResponseModel>> where TResponseModel : class, new() | ||
{ | ||
public JingetServiceHandler(string baseUri, bool ignoreSslErrors = false) : base(baseUri, ignoreSslErrors) { } | ||
public JingetServiceHandler(string baseUri, TimeSpan timeout, bool ignoreSslErrors = false) : base(baseUri, timeout, ignoreSslErrors) { } | ||
|
||
private async Task<TResponseModel?> ProcessTaskAsync(Func<Task<HttpResponseMessage>> task) | ||
/// <summary> | ||
/// Initializes a new instance of the <see cref="JingetServiceHandler{TResponseModel}"/> class with the specified base URI, timeout, and SSL error handling. | ||
/// </summary> | ||
/// <param name="baseUrl">The base URI for the service.</param> | ||
/// <param name="timeout">The timeout for HTTP requests.</param> | ||
/// <param name="ignoreSslErrors">A value indicating whether to ignore SSL errors.</param> | ||
public JingetServiceHandler(IServiceProvider serviceProvider, string baseUrl, string clientName = "jinget-client", TimeSpan? timeout = null) : base(serviceProvider, baseUrl, clientName, timeout) { } | ||
|
||
/// <summary> | ||
/// Processes the HTTP response, deserializes it into the specified response model, and invokes the ResponseDeserializedAsync event if successful. | ||
/// </summary> | ||
/// <param name="rawResponse">The raw response content as a string.</param> | ||
/// <param name="httpResponse">The HTTP response message.</param> | ||
/// <returns>The deserialized response model, or <c>null</c> if deserialization fails or an error occurs.</returns> | ||
private async Task<TResponseModel?> ProcessResponseAsync(string rawResponse, HttpResponseMessage httpResponse) | ||
{ | ||
TResponseModel? responseModel = default; | ||
|
||
try | ||
{ | ||
var response = await task(); | ||
Events?.OnServiceCalled(response); | ||
|
||
response.EnsureSuccessStatusCode(); | ||
var deserializedResponse = await base.ProcessResponseDefaultAsync<TResponseModel>(rawResponse, httpResponse); | ||
|
||
string rawResponse = await response.Content.ReadAsStringAsync(); | ||
Events?.OnRawResponseReceived(rawResponse); | ||
|
||
if (response.Content.Headers.ContentType != null) | ||
{ | ||
switch (response.Content.Headers.ContentType.MediaType) | ||
{ | ||
case MediaTypeNames.Application.Json: | ||
responseModel = rawResponse.Deserialize<TResponseModel>(strictPropertyMatching: false); | ||
break; | ||
case MediaTypeNames.Application.Xml: | ||
case MediaTypeNames.Text.Xml: | ||
responseModel = DeserializeXmlDescendantsFirst<TResponseModel>(rawResponse); | ||
break; | ||
default: | ||
// Handle unknown media type. | ||
Events?.OnExceptionOccurred(new InvalidOperationException($"Unsupported media type: {response.Content.Headers.ContentType.MediaType}")); | ||
break; | ||
} | ||
} | ||
else | ||
{ | ||
Events?.OnExceptionOccurred(new InvalidOperationException("content type was null")); | ||
} | ||
|
||
Events?.OnResponseDeserialized(responseModel); // Null check | ||
} | ||
catch (Exception ex) | ||
if (deserializedResponse != null && !EqualityComparer<TResponseModel>.Default.Equals(deserializedResponse, default)) | ||
{ | ||
Events?.OnExceptionOccurred(ex); // Null check | ||
return default; // or throw the exception. | ||
await Events.OnResponseDeserializedAsync(deserializedResponse); | ||
} | ||
|
||
return responseModel; | ||
return deserializedResponse; | ||
} | ||
|
||
public async Task<TResponseModel?> GetAsync(string url, Dictionary<string, string>? headers = null) | ||
=> await ProcessTaskAsync(async () => | ||
{ | ||
headers ??= new Dictionary<string, string> { { "Content-type", "application/json; charset=utf-8" } }; | ||
return await HttpClientFactory.GetAsync(url, headers); | ||
}); | ||
|
||
public async Task<TResponseModel?> PostAsync(object? content = null, Dictionary<string, string>? headers = null) | ||
=> await ProcessTaskAsync(async () => { | ||
headers ??= new Dictionary<string, string> { { "Content-type", "application/json; charset=utf-8" } }; | ||
return await HttpClientFactory.PostAsync("", content, headers); }); | ||
|
||
public async Task<TResponseModel?> PostAsync(string url, object? content = null, Dictionary<string, string>? headers = null) | ||
=> await ProcessTaskAsync(async () => | ||
{ | ||
headers ??= new Dictionary<string, string> { { "Content-type", "application/json; charset=utf-8" } }; | ||
return await HttpClientFactory.PostAsync(url, content, headers); | ||
}); | ||
|
||
public async Task<TResponseModel?> UploadFileAsync(string url, List<FileInfo>? files = null, Dictionary<string, string>? headers = null) | ||
=> await ProcessTaskAsync(async () => | ||
{ | ||
headers ??= new Dictionary<string, string> { { "Content-type", "application/json; charset=utf-8" } }; | ||
return await HttpClientFactory.UploadFileAsync(url, files, headers); | ||
}); | ||
|
||
public async Task<TResponseModel?> UploadFileAsync(string url, MultipartFormDataContent? multipartFormData = null, Dictionary<string, string>? headers = null) | ||
=> await ProcessTaskAsync(async () => | ||
{ | ||
headers ??= new Dictionary<string, string> { { "Content-type", "application/json; charset=utf-8" } }; | ||
return await HttpClientFactory.UploadFileAsync(url, multipartFormData, headers); | ||
}); | ||
|
||
public async Task<TResponseModel?> SendAsync(HttpRequestMessage message) => await ProcessTaskAsync(async () => await HttpClientFactory.SendAsync(message)); | ||
/// <summary> | ||
/// Makes an HTTP GET request to the specified URL and processes the response. | ||
/// </summary> | ||
/// <param name="requestUrl">The URL to make the GET request to.</param> | ||
/// <param name="requestHeaders">Optional headers to include in the request.</param> | ||
/// <returns>The deserialized response model, or <c>null</c> if an error occurs.</returns> | ||
public async Task<TResponseModel?> GetAsync(string requestUrl, Dictionary<string, string>? requestHeaders = null) | ||
=> await base.GetAsync(requestUrl, requestHeaders, ProcessResponseAsync); | ||
|
||
/// <summary> | ||
/// Makes an HTTP POST request with the specified content and processes the response. | ||
/// </summary> | ||
/// <param name="requestBody">The content to include in the POST request.</param> | ||
/// <param name="requestHeaders">Optional headers to include in the request.</param> | ||
/// <returns>The deserialized response model, or <c>null</c> if an error occurs.</returns> | ||
public async Task<TResponseModel?> PostAsync(object? requestBody = null, Dictionary<string, string>? requestHeaders = null) | ||
=> await base.PostAsync(requestBody, requestHeaders, ProcessResponseAsync); | ||
|
||
/// <summary> | ||
/// Makes an HTTP POST request to the specified URL with the specified content and processes the response. | ||
/// </summary> | ||
/// <param name="requestUrl">The URL to make the POST request to.</param> | ||
/// <param name="requestBody">The content to include in the POST request.</param> | ||
/// <param name="requestHeaders">Optional headers to include in the request.</param> | ||
/// <returns>The deserialized response model, or <c>null</c> if an error occurs.</returns> | ||
public async Task<TResponseModel?> PostAsync(string requestUrl, object? requestBody = null, Dictionary<string, string>? requestHeaders = null) | ||
=> await base.PostAsync(requestUrl, requestBody, requestHeaders, ProcessResponseAsync); | ||
|
||
/// <summary> | ||
/// Uploads files to the specified URL and processes the response. | ||
/// </summary> | ||
/// <param name="requestUrl">The URL to upload the files to.</param> | ||
/// <param name="files">The list of files to upload.</param> | ||
/// <param name="requestHeaders">Optional headers to include in the request.</param> | ||
/// <returns>The deserialized response model, or <c>null</c> if an error occurs.</returns> | ||
public async Task<TResponseModel?> UploadFilesAsync(string requestUrl, List<FileInfo>? files = null, Dictionary<string, string>? requestHeaders = null) | ||
=> await base.UploadFilesAsync(requestUrl, files, requestHeaders, ProcessResponseAsync); | ||
|
||
/// <summary> | ||
/// Uploads files to the specified URL using a multipart form data content and processes the response. | ||
/// </summary> | ||
/// <param name="requestUrl">The URL to upload the files to.</param> | ||
/// <param name="multipartFormData">The multipart form data content.</param> | ||
/// <param name="requestHeaders">Optional headers to include in the request.</param> | ||
/// <returns>The deserialized response model, or <c>null</c> if an error occurs.</returns> | ||
public async Task<TResponseModel?> UploadFilesAsync(string requestUrl, MultipartFormDataContent? multipartFormData = null, Dictionary<string, string>? requestHeaders = null) | ||
=> await base.UploadFilesAsync(requestUrl, multipartFormData, requestHeaders, ProcessResponseAsync); | ||
|
||
/// <summary> | ||
/// Sends an HTTP request message and processes the response. | ||
/// </summary> | ||
/// <param name="httpRequestMessage">The HTTP request message to send.</param> | ||
/// <returns>The deserialized response model, or <c>null</c> if an error occurs.</returns> | ||
public async Task<TResponseModel?> SendAsync(HttpRequestMessage httpRequestMessage) | ||
=> await base.SendAsync(httpRequestMessage, ProcessResponseAsync); | ||
} | ||
public class JingetServiceHandler : ServiceHandler<JingetServiceHandlerEvents> | ||
{ | ||
public JingetServiceHandler(string baseUri, bool ignoreSslErrors = false) : base(baseUri, ignoreSslErrors) { } | ||
public JingetServiceHandler(string baseUri, TimeSpan timeout, bool ignoreSslErrors = false) : base(baseUri, timeout, ignoreSslErrors) { } | ||
|
||
private async Task<string?> ProcessTaskAsync(Func<Task<HttpResponseMessage>> task) | ||
{ | ||
try | ||
{ | ||
var response = await task(); | ||
Events?.OnServiceCalled(response); | ||
|
||
response.EnsureSuccessStatusCode(); | ||
|
||
string rawResponse = await response.Content.ReadAsStringAsync(); | ||
Events?.OnRawResponseReceived(rawResponse); | ||
return rawResponse; | ||
} | ||
catch (Exception ex) | ||
{ | ||
Events?.OnExceptionOccurred(ex); // Null check | ||
return null; // or throw the exception. | ||
} | ||
} | ||
|
||
public async Task<string?> GetAsync(string url, Dictionary<string, string>? headers = null) | ||
=> await ProcessTaskAsync(async () => | ||
{ | ||
headers ??= new Dictionary<string, string> { { "Content-type", "application/json; charset=utf-8" } }; | ||
return await HttpClientFactory.GetAsync(url, headers); | ||
}); | ||
|
||
public async Task<string?> PostAsync(object? content = null, Dictionary<string, string>? headers = null) | ||
=> await ProcessTaskAsync(async () => | ||
{ | ||
headers ??= new Dictionary<string, string> { { "Content-type", "application/json; charset=utf-8" } }; | ||
return await HttpClientFactory.PostAsync("", content, headers); | ||
}); | ||
|
||
public async Task<string?> PostAsync(string url, object? content = null, Dictionary<string, string>? headers = null) | ||
=> await ProcessTaskAsync(async () => | ||
{ | ||
headers ??= new Dictionary<string, string> { { "Content-type", "application/json; charset=utf-8" } }; | ||
return await HttpClientFactory.PostAsync(url, content, headers); | ||
}); | ||
|
||
public async Task<string?> UploadFileAsync(string url, List<FileInfo>? files = null, Dictionary<string, string>? headers = null) | ||
=> await ProcessTaskAsync(async () => | ||
{ | ||
headers ??= new Dictionary<string, string> { { "Content-type", "application/json; charset=utf-8" } }; | ||
return await HttpClientFactory.UploadFileAsync(url, files, headers); | ||
}); | ||
|
||
public async Task<string?> UploadFileAsync(string url, MultipartFormDataContent? multipartFormData = null, Dictionary<string, string>? headers = null) | ||
=> await ProcessTaskAsync(async () => | ||
{ | ||
headers ??= new Dictionary<string, string> { { "Content-type", "application/json; charset=utf-8" } }; | ||
return await HttpClientFactory.UploadFileAsync(url, multipartFormData, headers); | ||
}); | ||
|
||
public async Task<string?> SendAsync(HttpRequestMessage message) => await ProcessTaskAsync(async () => await HttpClientFactory.SendAsync(message)); | ||
} | ||
/// <summary> | ||
/// Service handler for processing HTTP responses as raw strings. | ||
/// </summary> | ||
public class JingetServiceHandler : JingetServiceHandlerBase<JingetServiceHandlerEvents> | ||
{ | ||
/// <summary> | ||
/// Initializes a new instance of the <see cref="JingetServiceHandler"/> class with the specified base URI, timeout, and SSL error handling. | ||
/// </summary> | ||
/// <param name="baseUrl">The base URI for the service.</param> | ||
/// <param name="timeout">The timeout for HTTP requests.</param> | ||
/// <param name="ignoreSslErrors">A value indicating whether to ignore SSL errors.</param> | ||
public JingetServiceHandler(IServiceProvider serviceProvider, string baseUrl, string clientName = "jinget-client", TimeSpan? timeout = null) : base(serviceProvider, baseUrl, clientName, timeout) { } | ||
} |
Oops, something went wrong.