Updated all test methods to use asynchronous programming with
`async` and `await`, replacing synchronous calls with
`.GetAwaiter().GetResult()`. This improves readability and
aligns with modern C# practices.
Renamed test methods to reflect their asynchronous nature and
better describe their behavior. Updated exception handling to
validate HTTP methods and request URIs while maintaining
original assertions.
Applied changes consistently across multiple test classes,
including `CommonApiTests`, `EndpointAuthApiTests`,
`EndpointParamsApiTests`, `EndpointsApiTests`,
`ProfileApiTests`, `RecActionApiTests`, and `ResultApiTests`.
Added a new test class `EndpointsApiTests` to validate the `Endpoints` API functionality in the `ReC.Client`.
Tests include:
- Dependency injection resolution for the `Endpoints` API.
- Behavior of `CreateAsync` with minimal payload.
- Behavior of `UpdateAsync` with an unknown ID.
- Validation of `DeleteAsync` sending payload as query string.
Introduced necessary `using` directives and utilized the `CreateScopedClient` helper method for resource management.
Added `EndpointParamsApiTests` to validate the `EndpointParams`
API functionality. Introduced tests for dependency injection
resolution, `CreateAsync`, `UpdateAsync`, and `DeleteAsync`
methods to ensure proper behavior, including exception handling
and HTTP method verification. Utilized scoped clients for
resource management and introduced payload DTOs for API
operations.
Added the `EndpointAuthApiTests` class to test the `EndpointAuth` API.
Tests include:
- Dependency injection resolution (`ReCClient_endpoint_auth_api_is_resolvable_through_dependency_injection`).
- `CreateAsync` behavior with minimal payload.
- `UpdateAsync` behavior with an unknown ID.
- `DeleteAsync` behavior, ensuring payload is sent as a query string.
Introduced necessary `using` directives and utilized the `CreateScopedClient` helper method for scoped client creation. Added exception handling to validate API method behavior and ensure proper assertions on exceptions.
Introduced the `CommonApiTests` class to validate the behavior of the `ReCClient`'s `Common` API.
- Added `using` directives for namespaces related to procedures and commands to support the new tests.
- Verified dependency injection resolution for `ReCClient` and its `Common` API.
- Added tests for `CreateAsync`, `UpdateAsync`, and `DeleteAsync` methods to ensure proper handling of payloads and expected behavior:
- `CreateAsync_with_invalid_action_payload_throws_or_completes`: Tests invalid payload handling for `CreateAsync`.
- `UpdateAsync_with_body_payload_throws_or_completes`: Tests payload handling for `UpdateAsync`.
- `DeleteAsync_sends_payload_as_query_string`: Verifies query string construction for `DeleteAsync`.
Introduced a new `ProfileApiTests` class to test the `Profiles` API in the `ReC.Client`. Added test methods to verify API behavior, including dependency injection resolution, handling of unknown IDs, dynamic payload retrieval, update operations, and query string validation for delete operations.
Key changes:
- Added `ReCClient_profiles_api_is_resolvable_through_dependency_injection` test.
- Added `GetAsync_with_unknown_id_throws_not_found` test.
- Added `GetDynamicAsync_with_unknown_id_throws_not_found` test.
- Added `GetDynamicAsync_without_filters_returns_dynamic_payload_or_throws_not_found` test.
- Added `UpdateAsync_with_unknown_id_throws_or_completes` test.
- Added `DeleteAsync_sends_payload_as_query_string` test.
Included necessary `using` directives, scoped client creation, and exception handling to ensure robust test coverage for the `Profiles` API.
Introduced the `ResultApiTests` class to validate the behavior of the `Results` API client. Added test cases to ensure proper dependency injection, handle various API operations (`GetAsync`, `GetDynamicAsync`, `CreateAsync`, `UpdateAsync`, `DeleteAsync`), and verify expected outcomes such as exceptions, payload handling, and dynamic responses. Included necessary `using` directives to support the new tests.
Added a `using` directive for `System.Text.Json` to support JSON
operations. Introduced two new test methods:
`GetDynamicAsync_without_filters_returns_dynamic_payload_or_throws_not_found`
to validate the behavior of `GetDynamicAsync` without filters, and
`GetDynamicAsync_with_unknown_profile_throws_not_found` to ensure
proper handling of unknown profile IDs.
Added `GetDynamicAsync` methods to `ProfileApi`, `RecActionApi`,
and `ResultApi` to enable dynamic payload deserialization.
These methods support optional parameters for filtering and
are conditionally compiled for `NETFRAMEWORK` and other
frameworks, with nullable reference type support where
applicable. Internally, they reuse the existing `GetAsync<object>`
method for data retrieval.
Introduced a new test class `RecActionApiTests` to validate the behavior of the `RecActions` API client.
- Added tests for `GetAsync`, `CreateAsync`, `UpdateAsync`, `DeleteAsync`, and `InvokeAsync` methods to ensure proper handling of valid and invalid inputs.
- Verified dependency injection resolution for `RecClient` and `RecActions`.
- Included assertions for HTTP status codes, request methods, and query parameters.
- Handled edge cases such as missing test data with `Assert.Pass` or `Assert.Ignore`.
- Utilized scoped clients for test isolation and resource management.
These changes improve test coverage and ensure the reliability of the `RecActions` API client.
Introduce `RecClientTestBase` to streamline integration tests for `ReCClient`.
This abstract class uses `WebApplicationFactory` to create a test server
for `ReC.API` and configures a `ServiceProvider` with necessary services.
It includes helper methods for creating scoped `ReCClient` instances and
ensures proper resource cleanup via `IDisposable`.
Update `ReC.Tests.csproj` to include:
- `Microsoft.AspNetCore.Mvc.Testing` package for integration testing.
- Project references to `ReC.API` and `ReC.Client` for testing purposes.
These changes establish a reusable and maintainable testing infrastructure.
Updated the `try-catch` block in `Program.cs` to rethrow exceptions after logging them, ensuring proper error propagation. Added a `public partial class Program` declaration to enable splitting the `Program` class across multiple files. Adjusted closing braces to align with the new structure.
Updated GetAsync methods in ProfileApi, RecActionApi, and
ResultApi to return deserialized objects of type <T> instead
of raw HttpResponseMessage, improving usability.
Added conditional compilation (#if NETFRAMEWORK) to handle
nullable return types (T?) for non-NET Framework targets,
ensuring compatibility across .NET versions.
Replaced direct Http.GetAsync calls with using blocks for
proper disposal of HTTP responses. Introduced response
handling and deserialization via ReCClientHelpers to
streamline processing and logging.
Updated XML documentation to reflect the new behavior and
removed redundant parameters.
Enhanced `HandleResponseAsync` to return response body as a string and log successful responses. Introduced `JsonOptions` for consistent JSON serialization/deserialization. Added a generic `Deserialize<T>` method for deserializing JSON responses. Updated method signatures to support nullable reference types.
Updated `DeleteAsync` in `BaseCrudApi.cs` to serialize payloads into query strings to align with API expectations.
Added `UpdateAsync` to `CommonApi.cs` for payload-based updates, overriding inherited CRUD helpers to match the API's behavior.
Enhanced `GetAsync` in `ProfileApi.cs` to support optional profile filtering and default `includeActions` to `true`.
Refactored `InvokeAsync` in `RecActionApi.cs` to use `long` for `profileId`, support nullable `references`, and handle batches of RecActions.
Extended `GetAsync` in `ResultApi.cs` with new optional filters (`batchId`, `includeAction`, `includeProfile`, `lastBatch`) and updated query-building logic.
Enhanced ReCClientHelpers.cs with a new utility method:
- Added `BuildQueryFromObject<T>` to serialize objects into query strings.
- Skips `null` properties and escapes names/values for safety.
- Added `System.Collections` and `System.Reflection` namespaces to support reflection and collection operations.
This improves HTTP request handling by enabling dynamic query string generation from object payloads.
Introduced a new `ReCClientOptions` property to `BaseCrudApi`
and its derived classes to enhance flexibility and control
over client behavior. Updated constructors to accept an
optional `ReCClientOptions` parameter, with default options
applied when omitted.
Modified `CreateAsync`, `UpdateAsync`, and other methods in
`BaseCrudApi` to utilize the `Options.LogSuccessfulRequests`
property for more granular logging control. Updated derived
API classes (`CommonApi`, `EndpointAuthApi`, `EndpointParamsApi`,
`EndpointsApi`, `ProfileApi`, `RecActionApi`, and `ResultApi`)
to pass the `options` parameter to the base constructor.
Ensured compatibility with both `NETFRAMEWORK` and other
frameworks by using nullable annotations where applicable.
These changes improve the extensibility and maintainability
of the API client.
The HandleResponseAsync method was updated to include a new
optional parameter, `logSuccess`, which allows control over
whether successful HTTP responses are logged. The default
value is `true`. This change applies to both `NETFRAMEWORK`
and non-`NETFRAMEWORK` builds. The method's XML documentation
was updated to reflect this new behavior.
Updated `ReCClient` to support dependency injection for
`IOptions<ReCClientOptions>` and `ILogger`. Modified the
constructor to include an optional `IOptions` parameter,
allowing the use of configurable client options with
default values when omitted. Updated API component
initialization to pass `ReCClientOptions` for enhanced
configuration.
Added `Microsoft.Extensions.Logging` and
`Microsoft.Extensions.Options` to `using` directives.
Ensured compatibility with both `NETFRAMEWORK` and other
target frameworks by updating constructor signatures
accordingly.
Added an optional `configureOptions` parameter to `AddRecClient`
methods, enabling configuration of `ReCClientOptions`. Introduced
conditional compilation to handle nullability differences between
.NET Framework and other frameworks.
Implemented a private helper method `AddRecClientOptions` to ensure
default options are registered even when no configuration action is
provided. Updated `AddRecClient` overloads to use this helper.
Included `System.Net.Http` in `#if NETFRAMEWORK` directives to
maintain compatibility with .NET Framework.
Introduce the `ReCClientOptions` class in the new `ReC.Client`
namespace. This class includes the `LogSuccessfulRequests`
property, which allows users to enable or disable logging for
successful API requests via the injected `ILogger`. Failed
requests are unaffected and will always throw `ReCApiException`.
The property defaults to `true`. XML documentation is included
to describe the class and its behavior.
Refactored the `EnsureSuccessAsync` method to `HandleResponseAsync`
and added optional `ILogger` support for logging HTTP request
and response details.
- Added `using Microsoft.Extensions.Logging;` for logging.
- Log success responses with HTTP method, URI, status code,
and reason phrase.
- Updated exception message construction for clarity.
- Added conditional compilation for nullable `ILogger?`
in non-NET Framework targets.
- Improved code maintainability by consolidating logic.
Introduced optional ILogger support across BaseCrudApi and its
derived classes to enable logging of API call outcomes. Updated
constructors to accept an optional ILogger parameter, with
conditional compilation for .NET Framework compatibility.
Replaced EnsureSuccessAsync with HandleResponseAsync in CRUD
methods to integrate logging. Updated derived API classes
(CommonApi, EndpointAuthApi, EndpointParamsApi, EndpointsApi,
ProfileApi, RecActionApi, ResultApi) to pass ILogger to the base
class.
Added Microsoft.Extensions.Logging imports and ensured backward
compatibility by making ILogger optional and handling nullable
reference types in non-.NET Framework environments.
Updated the `ReCClient` constructor to include an optional `ILogger` parameter for logging API call outcomes. Added support for both .NET Framework and other frameworks by using non-generic and generic `ILogger` types, respectively. Updated API-related objects (`RecActionApi`, `ResultApi`, etc.) to accept and utilize the `ILogger` instance for enhanced logging functionality.
The return type of the `InvokeAsync` method has been changed from `Task<bool>` to `Task` for both overloads, removing the boolean return value for success indication.
The `<returns>` XML documentation tag has been removed, and a new `<exception>` tag has been added to document the potential `ReCApiException` thrown when the API responds with a non-success status code.
The implementation now uses `ReCClientHelpers.EnsureSuccessAsync` to handle API responses, replacing the previous `resp.IsSuccessStatusCode` check.
These changes improve clarity and align the method's behavior with standard practices for handling asynchronous operations and exceptions.
Updated `CreateAsync`, `UpdateAsync`, and `DeleteAsync` methods to return `Task` instead of `Task<bool>`. Removed `<returns>` documentation and added `<exception>` tags to indicate that a `ReCApiException` is thrown for non-successful API responses. Replaced `resp.IsSuccessStatusCode` checks with `ReCClientHelpers.EnsureSuccessAsync` to enforce exception-based error handling. These changes align with modern asynchronous error-handling practices.
Introduced the `EnsureSuccessAsync` method in `ReCClientHelpers.cs` to handle HTTP response validation asynchronously. This method throws a `ReCApiException` for non-success status codes, including detailed error information such as status code, reason phrase, HTTP method, URI, and response body (if available).
Updated `using` directives to support asynchronous operations and cancellation tokens. Removed redundant `#if NETFRAMEWORK` directive around `using System.Net.Http;` and adjusted `using System.Net.Http.Json;` placement for consistency.
Added exception handling for response body read failures to ensure status information is still propagated. Enhanced error reporting for failed HTTP requests.
A new `ReCApiException` class was introduced in the `ReC.Client` namespace to represent errors returned by the ReC API.
The class includes properties for detailed error information:
- `StatusCode`, `ReasonPhrase`, `ResponseBody`, `Method`, and `RequestUri`.
A constructor was added to initialize these properties. Conditional compilation directives ensure compatibility between .NET Framework and other .NET targets. The class is marked as `[Serializable]` for non-.NET Framework targets.
Updated the `InvokeAsync` method in the `ReC.Client.Api` namespace to use `using` statements for the `content` and `resp` objects. This change ensures proper disposal of these resources, improving memory management and preventing potential leaks. The functional behavior of the method remains unchanged.
Updated `CreateAsync<T>`, `UpdateAsync<T>`, and `DeleteAsync<T>`
methods to return a `bool` indicating success instead of
`HttpResponseMessage`. Added `using` statements to ensure proper
disposal of HTTP content and response objects. Simplified the
interface for better usability by leveraging `IsSuccessStatusCode`
to determine operation success.
Updated the project version, assembly version, file version, and informational version from 2.3.0-beta to 2.4.0-beta in the ReC.API.csproj file. This prepares the project for the next beta release.
Add AutoDetectHeaders option to RecAction config and handler. When enabled, automatically set Content-Type based on body content (JSON or XML) and default Accept to application/json if missing. Log warnings when headers are auto-detected. Improves robustness and makes header detection configurable.
EnableSensitiveDataLogging and EnableDetailedErrors are now configurable via appsettings.json under the "EfCore" section. Program.cs reads these values from configuration instead of hardcoding them, allowing runtime control of EF Core logging and error detail behavior.
Enhance InvokeRecActionViewCommandHandler to robustly handle invalid or non-strict HTTP header values. "Content-Type" and "Authorization" headers are now set using strict parsing with fallback to TryAddWithoutValidation on failure, logging warnings for easier debugging. General headers and API key headers also use this strict-then-fallback approach, making HTTP request construction more tolerant of malformed values and reducing runtime errors.
Inject optional ILogger into InvokeRecActionViewCommandHandler for enhanced logging. When adding HTTP headers, catch FormatException and log a warning with relevant context, then fall back to TryAddWithoutValidation. This increases robustness and observability for malformed or non-standard headers.
Wrap ExecuteScalarAsync in try-catch blocks in BodyQueryBehavior and HeaderQueryBehavior. Throw DataIntegrityException with detailed context if SQL execution fails, aiding in diagnosing malformed or problematic stored SQL queries.
Throw DataIntegrityException when body or header queries return
null, no result, or invalid JSON. Remove ILogger and related
logging from HeaderQueryBehavior for simplification. This change
ensures data integrity issues are surfaced immediately.
Refactored BodyQueryBehavior and HeaderQueryBehavior to operate on collections of RecActionViewDto instead of single instances. Moved SQL execution and property assignment logic into private helper methods using ADO.NET commands. Improved null checks and logging, and updated type constraints to reflect the new usage. Behaviors now return the modified collection after processing.
Replaced string-based entity identifiers in CRUD procedure and command classes with a strongly-typed EntityType enum. Updated all relevant handlers and records to use the new enum property, improving type safety and maintainability. Added necessary using directives and updated documentation comments to reflect these changes.
Refactored DeleteObjectProcedureValidator, InsertObjectProcedureValidator, and UpdateObjectProcedureValidator to use .IsInEnum() for validating the Entity property. This replaces custom or hardcoded checks with enum-based validation, improving consistency, maintainability, and robustness across all validators.
Introduced the EntityType enum to represent target entities for stored procedure operations, along with XML documentation and mapping comments. Added EntityTypeExtensions with a ToDbString method for consistent DB string conversion. Updated StoredProcedureBuilder to support adding EntityType parameters, improving type safety and maintainability. Minor formatting and using directive adjustments included.
Deleted FakeRequest.cs and ResultType.cs, removing the FakeRequest class (with Body and Header properties) and the ResultType enum (Full, OnlyHeader, OnlyBody). These types are no longer needed in the codebase.
Introduced UpdateObjectProcedureValidator using FluentValidation to enforce constraints on UpdateObjectProcedure fields, including ID checks and maximum length restrictions on various properties and nested objects.
Introduced ReadResultViewQueryValidator to enforce that at least one filter (Id, ActionId, ProfileId, or BatchId) is provided. Also validates that numeric IDs are greater than 0 and BatchId is not empty when present.
Introduced ReadRecActionViewQueryValidator using FluentValidation to ensure ProfileId, if provided, is greater than 0. Returns a specific validation message if the rule is violated.
Introduced ReadProfileViewQueryValidator using FluentValidation to ensure the Id property, if provided, is greater than 0. Includes a custom error message for invalid Id values.
Introduce InsertResultCommandValidator using FluentValidation to enforce required and value constraints on ActionId and References.BatchId properties, including custom error messages.
Introduced DeleteObjectProcedureValidator using FluentValidation to ensure Start is greater than 0 and End is greater than or equal to Start, with custom error messages for each rule.