Skip to content

Customizing Long-Running Operations

ARM long-running (asynchronous) operation templates allow you to customize the LRO headers returned in the initial response, while retaining the correct finalResult value that matches the result of the operation. This is done using the LroHeaders template parameter available on all async operation templates. The headers appear in the 201 Created response for PUT operations and in the 202 Accepted response for PATCH, DELETE, and POST operations.

The Azure.ResourceManager library provides the following header models for long-running operations:

Header ModelDescription
ArmAsyncOperationHeaderProvides the Azure-AsyncOperation header for polling
ArmLroLocationHeaderProvides the Location header for polling
ArmCombinedLroHeadersProvides both Azure-AsyncOperation and Location headers for polling

Each header model accepts a FinalResult parameter that indicates the type of the logical result of the operation. It is important that this value matches what the operation actually returns.

The ArmResourceCreateOrReplaceAsync and ArmResourceCreateOrUpdateAsync templates use ArmAsyncOperationHeader by default with the resource as the final result.

op createOrUpdate is ArmResourceCreateOrReplaceAsync<MyResource>;

The default LroHeaders for PUT is:

ArmAsyncOperationHeader<FinalResult = MyResource> & Azure.Core.Foundations.RetryAfterHeader

To use a Location header instead of Azure-AsyncOperation, override the LroHeaders parameter. Make sure FinalResult is set to the resource type so that the final polling result is correct:

op createOrUpdate is ArmResourceCreateOrReplaceAsync<
MyResource,
LroHeaders = ArmLroLocationHeader<FinalResult = MyResource> &
Azure.Core.Foundations.RetryAfterHeader
>;

To return both Azure-AsyncOperation and Location headers, use ArmCombinedLroHeaders. Set FinalResult to the resource type:

op createOrUpdate is ArmResourceCreateOrReplaceAsync<
MyResource,
LroHeaders = ArmCombinedLroHeaders<FinalResult = MyResource> &
Azure.Core.Foundations.RetryAfterHeader
>;

The ArmResourcePatchAsync and ArmCustomPatchAsync templates use ArmLroLocationHeader by default with the resource as the final result.

op update is ArmResourcePatchAsync<MyResource, MyResourceProperties>;

The default LroHeaders for PATCH is:

ArmLroLocationHeader<FinalResult = MyResource> & Azure.Core.Foundations.RetryAfterHeader

Customizing to use an Azure-AsyncOperation header

Section titled “Customizing to use an Azure-AsyncOperation header”

To use an Azure-AsyncOperation header instead of Location, override the LroHeaders parameter. Set FinalResult to the resource type:

op update is ArmResourcePatchAsync<
MyResource,
MyResourceProperties,
LroHeaders = ArmAsyncOperationHeader<FinalResult = MyResource> &
Azure.Core.Foundations.RetryAfterHeader
>;

To return both headers, use ArmCombinedLroHeaders. Set FinalResult to the resource type:

op update is ArmResourcePatchAsync<
MyResource,
MyResourceProperties,
LroHeaders = ArmCombinedLroHeaders<FinalResult = MyResource> &
Azure.Core.Foundations.RetryAfterHeader
>;

The ArmResourceDeleteWithoutOkAsync template uses ArmLroLocationHeader by default with void as the final result, since delete operations do not return a resource body on completion.

op delete is ArmResourceDeleteWithoutOkAsync<MyResource>;

The default LroHeaders for DELETE is:

ArmLroLocationHeader<FinalResult = void> & Azure.Core.Foundations.RetryAfterHeader

Customizing to use an Azure-AsyncOperation header

Section titled “Customizing to use an Azure-AsyncOperation header”

To use an Azure-AsyncOperation header instead of Location, override the LroHeaders parameter. Keep FinalResult as void because delete operations do not return a resource body:

op delete is ArmResourceDeleteWithoutOkAsync<
MyResource,
LroHeaders = ArmAsyncOperationHeader<FinalResult = void> & Azure.Core.Foundations.RetryAfterHeader
>;

To return both headers, use ArmCombinedLroHeaders. Keep FinalResult as void:

op delete is ArmResourceDeleteWithoutOkAsync<
MyResource,
LroHeaders = ArmCombinedLroHeaders<FinalResult = void> & Azure.Core.Foundations.RetryAfterHeader
>;

The ArmResourceActionAsync template uses ArmLroLocationHeader by default. The FinalResult should match the response type of the action. For actions that return no content, use ArmResourceActionNoResponseContentAsync where FinalResult defaults to void.

op startMigration is ArmResourceActionAsync<MyResource, MigrationRequest, MigrationResponse>;

The default LroHeaders for a POST action is:

ArmLroLocationHeader<FinalResult = MigrationResponse> & Azure.Core.Foundations.RetryAfterHeader
op restart is ArmResourceActionNoResponseContentAsync<MyResource, RestartRequest>;

The default LroHeaders for a no-content POST action is:

ArmLroLocationHeader<FinalResult = void> & Azure.Core.Foundations.RetryAfterHeader

Customizing to use an Azure-AsyncOperation header

Section titled “Customizing to use an Azure-AsyncOperation header”

Override the LroHeaders parameter. Set FinalResult to match the response type of the action:

op startMigration is ArmResourceActionAsync<
MyResource,
MigrationRequest,
MigrationResponse,
LroHeaders = ArmAsyncOperationHeader<FinalResult = MigrationResponse> &
Azure.Core.Foundations.RetryAfterHeader
>;

For an action with no response content, set FinalResult to void:

op restart is ArmResourceActionNoResponseContentAsync<
MyResource,
RestartRequest,
LroHeaders = ArmAsyncOperationHeader<FinalResult = void> & Azure.Core.Foundations.RetryAfterHeader
>;

To return both headers, use ArmCombinedLroHeaders. Set FinalResult to match the response type:

op startMigration is ArmResourceActionAsync<
MyResource,
MigrationRequest,
MigrationResponse,
LroHeaders = ArmCombinedLroHeaders<FinalResult = MigrationResponse> &
Azure.Core.Foundations.RetryAfterHeader
>;

For an action with no response content:

op restart is ArmResourceActionNoResponseContentAsync<
MyResource,
RestartRequest,
LroHeaders = ArmCombinedLroHeaders<FinalResult = void> & Azure.Core.Foundations.RetryAfterHeader
>;