diff --git a/uplink.NET/uplink.NET.Sample/uplink.NET.Sample.Shared/ViewModels/BucketContentViewModel.cs b/uplink.NET/uplink.NET.Sample/uplink.NET.Sample.Shared/ViewModels/BucketContentViewModel.cs
index 7d082f12..748d6674 100644
--- a/uplink.NET/uplink.NET.Sample/uplink.NET.Sample.Shared/ViewModels/BucketContentViewModel.cs
+++ b/uplink.NET/uplink.NET.Sample/uplink.NET.Sample.Shared/ViewModels/BucketContentViewModel.cs
@@ -115,7 +115,7 @@ public async Task InitAsync()
{
var bucket = await _bucketService.GetBucketAsync(BucketName);
var listOptions = new ListObjectsOptions();
- var objects = await _objectService.ListObjectsAsync(bucket, listOptions);
+ var objects = await _objectService.ListObjectsAsync(bucket, listOptions, null, 1000);
foreach (var obj in objects.Items)
{
var entry = new BucketEntryViewModel(this, _bucketService, _objectService);
diff --git a/uplink.NET/uplink.NET.Test/ObjectServiceTest.cs b/uplink.NET/uplink.NET.Test/ObjectServiceTest.cs
index 492e27fb..561f3827 100644
--- a/uplink.NET/uplink.NET.Test/ObjectServiceTest.cs
+++ b/uplink.NET/uplink.NET.Test/ObjectServiceTest.cs
@@ -606,6 +606,36 @@ public async Task CopyObject_CopiesObject_InDifferentBucket()
}
}
+ [TestMethod]
+ public async Task ListObjects_WithCursorAndMaxEntries()
+ {
+ string bucketname = "listobject-with-cursor-maxentries";
+
+ await _bucketService.CreateBucketAsync(bucketname);
+ var bucket = await _bucketService.GetBucketAsync(bucketname);
+ byte[] bytesToUpload = GetRandomBytes(2048);
+
+ var uploadOperation1 = await _objectService.UploadObjectAsync(bucket, "myfile1.txt", new UploadOptions(), bytesToUpload, false);
+ await uploadOperation1.StartUploadAsync();
+ var uploadOperation2 = await _objectService.UploadObjectAsync(bucket, "myfile2.txt", new UploadOptions(), bytesToUpload, false);
+ await uploadOperation2.StartUploadAsync();
+ var uploadOperation3 = await _objectService.UploadObjectAsync(bucket, "myfile3.txt", new UploadOptions(), bytesToUpload, false);
+ await uploadOperation3.StartUploadAsync();
+
+ var listOptions = new ListObjectsOptions { MaxEntries = 2 };
+ var objectList = await _objectService.ListObjectsAsync(bucket, listOptions);
+
+ Assert.AreEqual(2, objectList.Items.Count);
+ Assert.AreEqual("myfile1.txt", objectList.Items[0].Key);
+ Assert.AreEqual("myfile2.txt", objectList.Items[1].Key);
+
+ listOptions.Cursor = objectList.Items[1].Key;
+ var objectList2 = await _objectService.ListObjectsAsync(bucket, listOptions);
+
+ Assert.AreEqual(1, objectList2.Items.Count);
+ Assert.AreEqual("myfile3.txt", objectList2.Items[0].Key);
+ }
+
public static byte[] GetRandomBytes(long length)
{
byte[] bytes = new byte[length];
@@ -640,6 +670,7 @@ public async Task CleanupAsync()
await DeleteBucketAsync("copyobject-copies-object-samebucket");
await DeleteBucketAsync("copyobject-copies-object-diffbucket1");
await DeleteBucketAsync("copyobject-copies-object-diffbucket2");
+ await DeleteBucketAsync("listobject-with-cursor-maxentries");
}
private async Task DeleteBucketAsync(string bucketName)
diff --git a/uplink.NET/uplink.NET/Interfaces/IObjectService.cs b/uplink.NET/uplink.NET/Interfaces/IObjectService.cs
index 483124f1..40127750 100644
--- a/uplink.NET/uplink.NET/Interfaces/IObjectService.cs
+++ b/uplink.NET/uplink.NET/Interfaces/IObjectService.cs
@@ -106,6 +106,15 @@ public interface IObjectService
/// The list of found objects within the bucket and with the given ListOptions or throws an ObjectListException
Task ListObjectsAsync(Bucket bucket, ListObjectsOptions listObjectsOptions);
///
+ /// Lists objects within a bucket with pagination support
+ ///
+ /// The Bucket to list entries from
+ /// Options for the listing
+ /// The cursor value to start listing from
+ /// The maximum number of entries to return
+ /// The list of found objects within the bucket and with the given ListOptions or throws an ObjectListException
+ Task ListObjectsAsync(Bucket bucket, ListObjectsOptions listObjectsOptions, string cursor, int maxEntries);
+ ///
/// Gets the specific object
///
/// The Bucket where the object resides in
diff --git a/uplink.NET/uplink.NET/Models/ListObjectsOptions.cs b/uplink.NET/uplink.NET/Models/ListObjectsOptions.cs
index 4062f1da..c3745889 100644
--- a/uplink.NET/uplink.NET/Models/ListObjectsOptions.cs
+++ b/uplink.NET/uplink.NET/Models/ListObjectsOptions.cs
@@ -29,6 +29,10 @@ public class ListObjectsOptions
/// Custom includes CustomMetadata in the results.
///
public bool Custom { get; set; }
+ ///
+ /// MaxEntries sets the maximum number of entries to return.
+ ///
+ public int MaxEntries { get; set; }
internal SWIG.UplinkListObjectsOptions ToSWIG()
{
@@ -38,6 +42,7 @@ internal SWIG.UplinkListObjectsOptions ToSWIG()
ret.recursive = Recursive;
ret.system = System;
ret.custom = Custom;
+ ret.max_entries = MaxEntries;
return ret;
}
diff --git a/uplink.NET/uplink.NET/Services/ObjectService.cs b/uplink.NET/uplink.NET/Services/ObjectService.cs
index 11c13a12..6829ad42 100644
--- a/uplink.NET/uplink.NET/Services/ObjectService.cs
+++ b/uplink.NET/uplink.NET/Services/ObjectService.cs
@@ -158,6 +158,13 @@ public async Task ListObjectsAsync(Bucket bucket, ListObjectsOptions
}
}
+ public async Task ListObjectsAsync(Bucket bucket, ListObjectsOptions listObjectsOptions, string cursor, int maxEntries)
+ {
+ listObjectsOptions.Cursor = cursor;
+ listObjectsOptions.MaxEntries = maxEntries;
+ return await ListObjectsAsync(bucket, listObjectsOptions).ConfigureAwait(false);
+ }
+
public async Task GetObjectAsync(Bucket bucket, string targetPath)
{
using (var objectResult = await Task.Run(() => SWIG.storj_uplink.uplink_stat_object(_access._project, bucket.Name, targetPath)).ConfigureAwait(false))