ASP.NET Core's ValidationAttributeAdapterProvider has no adapter for
EnumDataTypeAttribute, so its ErrorMessage is never passed through the
IStringLocalizer and the raw localization key is returned to the client,
unlike every other common validation attribute.
Add EnumDataTypeAttributeAdapter and return it from
AbpValidationAttributeAdapterProvider.
ChildUnitOfWork subscribed a lambda to the parent's Failed and Disposed
events in its constructor and never unsubscribed, so every nested unit of
work left two delegates on the parent for the parent's whole lifetime.
Each delegate also captured the child, keeping disposed child instances
alive.
Forward the Failed and Disposed events straight to the parent with event
accessors instead, so nothing accumulates on the parent.
Handlers attached to a child still receive the parent's events with the
same sender and arguments, but their relative order can change: a handler
subscribed through a child now runs at the position where it was
subscribed, rather than where the child was constructed.
This change hardens `AbpUnitOfWorkMiddleware` to avoid invalid second completion attempts when the response starts during end-of-pipeline UoW completion, and to skip early completion while a shared child UoW scope is still active. It adds active child-scope tracking in `UnitOfWorkExtensions`/`ChildUnitOfWork`, updates option docs to clarify behavior, and adds MVC tests plus controller/event-handler scenarios covering child-scope response flush and event-driven response writes during completion.
- Enable globally via CompleteUnitOfWorkOnResponseStarting or per path via the Urls list
- OpenIddict opts in its endpoints so token/session rows commit before the response
- IBlobPipelineContributor pipeline; encryption runs innermost with an authenticated end check
- Adapt FileSystem/AWS to forward-only streams; fail early on unsupported AES-GCM
- Introduced IByteArrayEncryptionService interface for encrypting and decrypting binary data with authenticated encryption.
- Implemented methods for encrypting and decrypting byte arrays and streams, including options for passphrase and salt.
- Enhanced blob storing tests to cover encryption scenarios, including tenant-specific passphrases and custom pipeline contributors.
- Added FakeInMemoryBlobProvider and various test containers to facilitate testing of blob storage with encryption.
- Created unit tests for ByteArrayEncryptionService to validate encryption and decryption functionality, including edge cases for tampered data and oversized chunks.
- Treat QUERY as a safe method like GET: excluded from audit logging and non-transactional UOW
- Add HTTP verb constants and Is* helpers to HttpMethodHelper
Add an ITimezoneProvider.ConvertUnspecifiedToUtc helper that computes the
UTC ticks and keeps boundary values unchanged instead of throwing, then use
it in the System.Text.Json and Newtonsoft converters and the MVC model
binder. Normalize the Volo.Docs commit date filters to UTC for consistency.
AbpDateTimeConverterBase.Normalize converts an Unspecified DateTime to UTC via
`new DateTimeOffset(value, offset).UtcDateTime` when the clock is UTC and a user
timezone is set. For values within the timezone offset distance of
DateTime.MinValue/MaxValue (most notably the DateTime.MinValue placeholder), this
throws ArgumentOutOfRangeException. The exception was swallowed and logged as
"Could not convert DateTime with unspecified Kind using timezone '...'." on every
serialization, flooding logs for positive-offset users (e.g. Asia/Shanghai +08:00).
Catch the boundary ArgumentOutOfRangeException explicitly, keep the value unchanged,
and log it at Debug level instead of Warning so it stays traceable without polluting
production logs. Other unexpected failures still log a warning.
Also make Volo.Docs GitHubDocumentSource return a Utc-kind placeholder
(DateTime.SpecifyKind(DateTime.MinValue, Utc)) and use Author.Date.UtcDateTime, so it
no longer emits Unspecified placeholders in the first place.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>