What is your developer-dependent CMS actually costing you? Calculate your costs and get a full report
What is your developer-dependent CMS actually costing you? Calculate your costs and get a full report
SDKs
Create, update and delete URL redirections in bulk, and export and import them as Excel spreadsheets, with the Agility CMS .NET Management SDK 2.0.
client.UrlRedirections creates, updates and deletes an instance's URL redirections, and exports and imports them as Excel spreadsheets.
Note: URL redirection management is new in 2.0. If you're upgrading from 1.x, see Migrating to 2.0.
These are the same redirections editors manage in Agility under Settings → URL Redirections. For how they work, see URL Redirections.
The examples assume a client created as shown in the Intro, and guid set to your instance GUID. The redirection types are in Agility.Management.Sdk.Models:
using Agility.Management.Sdk;
using Agility.Management.Sdk.Models;
Every method also takes an optional CancellationToken cancellationToken as its last parameter. The signatures below leave it out.
SaveUrlRedirectionsAsync creates and updates up to 250 redirections in one call. Set UrlRedirectionID to 0 to create a redirection, or to an existing ID to update it.
UrlRedirectionSaveResult saved = await client.UrlRedirections.SaveUrlRedirectionsAsync(guid,
[
new UrlRedirection { UrlRedirectionID = 0, OriginUrl = "/old-page", DestinationUrl = "/new-page", HttpCode = 301 },
new UrlRedirection { UrlRedirectionID = 0, OriginUrl = "/promo", DestinationUrl = "https://example.com/sale", HttpCode = 302 },
]);
An update replaces the whole redirection, so send every property you want to keep.
| Property | What it holds |
|---|---|
UrlRedirectionID | 0 to create, or the ID of the redirection to update |
OriginUrl | The URL or path to redirect from. It must be unique in the instance. |
DestinationUrl | The URL or path to redirect to |
HttpCode | 301 (permanent) or 302 (temporary) |
DestinationLocale | Optional. The locale code of the destination URL, such as en-us. |
OriginLocales | Optional. The locale codes the origin URL applies to. Leave it null or empty to apply it to every locale. |
Content | Optional. Content served for the redirect instead of a Location header. |
Signature: Task<UrlRedirectionSaveResult> SaveUrlRedirectionsAsync(string instanceGuid, IReadOnlyList<UrlRedirection> redirections)
A save doesn't fail as a whole because of one bad item. Items that fail validation, or whose origin URL is already used by another redirection, are skipped. The result lists every item under Created, Updated or Skipped:
foreach (var item in saved.Created ?? [])
{
Console.WriteLine($"Created {item.OriginUrl} (ID: {item.UrlRedirectionID})");
}
foreach (var item in saved.Skipped ?? [])
{
Console.WriteLine($"Skipped item {item.Index} ({item.OriginUrl}): {item.Reason}");
}
Index is the item's zero-based position in the list you sent, and Reason says why a skipped item was skipped. Use the UrlRedirectionID of a created item to update or delete it later.
DeleteUrlRedirectionsAsync deletes up to 250 redirections by ID.
UrlRedirectionDeleteResult deleted = await client.UrlRedirections.DeleteUrlRedirectionsAsync(guid, [12, 13]);
Console.WriteLine($"Deleted: {string.Join(", ", deleted.Deleted ?? [])}");
Console.WriteLine($"Not found: {string.Join(", ", deleted.NotFound ?? [])}");
Deleted lists the IDs that were deleted. NotFound lists the IDs that didn't match an active redirection. Passing an empty list throws an ArgumentException before any request is sent.
Signature: Task<UrlRedirectionDeleteResult> DeleteUrlRedirectionsAsync(string instanceGuid, IEnumerable<int> redirectionIds)
The Management API has no call that lists redirections. To get them all, with their IDs, export them as a spreadsheet. You can edit the spreadsheet and import it back to update many redirections at once.
ExportUrlRedirectionsAsync returns every active redirection as an Excel (.xlsx) file. Dispose the stream when you're done with it.
await using (var export = await client.UrlRedirections.ExportUrlRedirectionsAsync(guid))
await using (var file = File.Create("redirections.xlsx"))
{
await export.CopyToAsync(file);
}
Signature: Task<Stream> ExportUrlRedirectionsAsync(string instanceGuid)
ImportUrlRedirectionsAsync imports redirections from an Excel (.xlsx) file of up to 5,000 rows. It uses the same columns as the export, so you can export, edit and re-import.
await using var edited = File.OpenRead("redirections.xlsx");
UrlRedirectionSaveResult imported = await client.UrlRedirections.ImportUrlRedirectionsAsync(guid, edited);
foreach (var row in imported.Skipped ?? [])
{
Console.WriteLine($"Row {row.Index} skipped: {row.Reason}");
}
| Column | Notes |
|---|---|
OriginURL | Required |
DestinationURL | Required |
HTTPCode | Optional. Defaults to 301. |
OriginLangCodes | Optional. Locale codes, separated by semicolons. |
DestinationLangCode | Optional |
Content | Optional |
UrlRedirectionID | Optional. A row with an ID updates that redirection; a row without one creates a redirection. |
The result has the same shape as a save. Rows that fail are skipped and reported, and Index is the row number in the file. The header is row 1.
The SDK doesn't dispose the stream you pass. fileName sets the file name sent with the upload; the default is redirections.xlsx.
Signature: Task<UrlRedirectionSaveResult> ImportUrlRedirectionsAsync(string instanceGuid, Stream file, string fileName = "redirections.xlsx")
Every error from the API or the network throws an AgilityManagementException. It carries the HTTP status code, the API's own message and a request ID. Items the API skips are reported in the result, not thrown.
try
{
var saved = await client.UrlRedirections.SaveUrlRedirectionsAsync(guid, redirections);
}
catch (AgilityManagementException ex)
{
Console.Error.WriteLine($"{ex.StatusCode}: {ex.ApiMessage} (request {ex.RequestId})");
}
Saves, deletes and imports are never retried. The export is a read, so it's retried automatically on temporary failures. See the Intro for the full list of exceptions and the retry rules.