Expand documentation on `[Obsolete]` static APIs and sync wrappers,
emphasizing their maintained status and appropriate use cases.
- Added detailed examples for `BuildStaticClient` and `Create`
in VB.NET and C#, including configuration options.
- Updated `TaskSyncExtensions.Sync` section with warnings about
potential deadlocks and recommendations for `async/await`.
- Introduced "6.3 Mid-Term Recommendation" to guide migration
to DI and async patterns.
- Highlighted scenarios where static APIs and sync wrappers
remain appropriate, such as legacy .NET Framework projects
or quick-start use cases.
- Clarified that `[Obsolete]` is a reminder, not a breaking change.
The solution file (ReC.sln) was updated to include the new
documentation file `docs\ReC.Client.xwiki` under the "Solution
Items" section. This change ensures the file is part of the
solution for better organization and accessibility.
Updated `RecActions.InvokeAsync(...).Sync()` to align with migration guidelines, marking `Sync()` as `[Obsolete]` and recommending `async/await` for asynchronous patterns.
Enhanced `BuildStaticClient` methods to include an optional `configureOptions` parameter for flexible `ReCClientOptions` configuration. Added conditional compilation for nullable reference type compatibility across .NET Framework and modern .NET versions.
Updated `Services.AddRecClient` calls to support `configureOptions`. Retained `[Obsolete]` on static helpers to encourage dependency injection (`services.AddRecClient(...)`) for new code.
Revised migration notes to emphasize deprecation of synchronous methods, static helpers, and the importance of adopting modern async and DI patterns. Clarified changes to `GetAsync` methods, error handling with `ReCApiException`, and deserialization behavior.
Comprehensively updated the documentation for the ReC.Client
library to improve usability and align with modern .NET
development practices. Key changes include:
- Added an introduction to the library, its purpose, and
supported frameworks (.NET 8 and .NET Framework 4.6.2).
- Documented core features like DI support, typed APIs,
consistent error handling, and flexible GET methods.
- Provided installation and setup instructions with examples
in VB.NET and C#.
- Explained usage patterns for GET endpoints (typed and
dynamic), CRUD operations, and invoking RecActions.
- Highlighted error handling via ReCApiException with examples.
- Added a section on testing with in-process API testing
recommendations.
- Marked static APIs and synchronous helpers as [Obsolete],
explaining limitations and providing migration tips.
- Provided migration guidance for recent API changes, such as
`GetAsync<T>` returning deserialized values and unified
error handling.
- Addressed FAQs about new patterns and deprecated methods.
These updates aim to modernize the library, promote best
practices, and simplify adoption for developers.
Renamed `GetDynamicAsync` to `GetAsync` across `ProfileApi.cs`,
`RecActionApi.cs`, and `ResultApi.cs` to improve consistency
and align with naming conventions for asynchronous methods.
Updated XML documentation to clarify that the non-generic
`GetAsync` overload returns a dynamically deserialized payload,
typically a `System.Text.Json.JsonElement`. Highlighted its
relation to the generic `GetAsync<T>` method.
Adjusted method signatures for both `NETFRAMEWORK` and
non-`NETFRAMEWORK` code paths. Updated test files
(`ProfileApiTests.cs`, `RecActionApiTests.cs`, and
`ResultApiTests.cs`) to reflect the renaming, including
test method names and assertions.
These changes enhance code readability, maintainability,
and consistency.
The `TaskSyncExtensions` class and its methods (`Sync` and
`Sync<TResult>`) have been marked as `[System.Obsolete]`. These
methods are no longer recommended due to the risk of deadlocks
and unexpected behavior caused by synchronous blocking.
Developers are advised to use `async/await` patterns instead.
The warning messages indicate that these methods will be
removed in a future release.
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.