Undelete Request Handler
The UndeleteRequestHandlerAsync is the base class that handles Undelete service requests. It restores a record that was previously soft deleted.
From Serenity 10.5.0, Sergen generates asynchronous handlers (
UndeleteRequestHandlerAsync) and endpoint actions by default. The synchronousUndeleteRequestHandleris kept for backward compatibility and is marked obsolete — it will be deprecated in a future version. New code — and code generated by Sergen — should use the async variants.
Sergen only generates an Undelete handler for rows that support soft delete, i.e. rows implementing IIsActiveDeletedRow or IIsDeletedRow. For a row without an IsActive/IsDeleted field (which is hard-deleted), there is nothing to undelete, so no handler is generated.
Generated Handler
For a row that supports soft delete, Sergen generates:
using MyRow = MyProject.Administration.UserRow;
namespace MyProject.Administration;
public interface IUserUndeleteHandler : IUndeleteHandlerAsync<MyRow> { }
public class UserUndeleteHandler(IRequestContext context)
: UndeleteRequestHandlerAsync<MyRow>(context), IUserUndeleteHandler
{
}
The class derives from the generic UndeleteRequestHandlerAsync<TRow> and IUndeleteRequestHandler.
UndeleteRequestHandlerAsync<TRow>itself derives from the fully generic UndeleteRequestHandlerAsync<TRow, TUndeleteRequest, TUndeleteResponse> — the extra arguments let you customize the request and response types if you ever need an undelete handler with a custom request/response.
The Service Endpoint
The endpoint exposes a single Undelete action:
[Route("Services/Administration/User/[action]")]
[ConnectionKey(typeof(MyRow)), ServiceAuthorize(typeof(MyRow))]
public class UserEndpoint : ServiceEndpoint
{
[HttpPost, AuthorizeDelete(typeof(MyRow))]
public Task<UndeleteResponse> Undelete(IUnitOfWork uow, UndeleteRequest request,
[FromServices] IUserUndeleteHandler handler, CancellationToken cancellationToken = default)
{
return handler.UndeleteAsync(uow, request, cancellationToken);
}
}
The Request and Response
The request is an UndeleteRequest:
public class UndeleteRequest : ServiceRequest
{
public object? EntityId { get; set; }
}
It only contains the ID of the record to restore. The response is an UndeleteResponse:
public class UndeleteResponse : ServiceResponse
{
public bool WasNotDeleted { get; set; }
}
WasNotDeleted is true if the record was not actually soft-deleted (e.g. it was already restored, or its IsActive was not -1).
What Undelete Does
Depending on the row type:
- For IIsActiveDeletedRow rows, the handler issues
UPDATE ... SET IsActive = 1whereIsActive = -1, restoring the record to active. - For IIsDeletedRow rows, it sets
IsDeleted = false.
If the row type doesn't implement one of these interfaces, the handler raises an error, because there is no way to undelete a hard-deleted record.
Lifecycle Methods
The main overridable methods on UndeleteRequestHandlerAsync are:
OnBeforeUndeleteAsync()— called before the undelete is executed.OnAfterUndeleteAsync()— called after the undelete succeeds.OnReturnAsync()— called just before the response is returned.
Each accepts a CancellationToken cancellationToken = default and returns Task. Call the base implementation first when overriding.
OnBeforeUndeleteAsync/OnAfterUndeleteAsync also invoke any registered IUndeleteBehavior.OnBeforeUndeleteAsync / OnAfterUndeleteAsync.