This topic describes how to upload objects to a versioning-enabled bucket.

Simple upload

When you upload an object to a versioning-enabled bucket, OSS automatically adds a unique version ID for the uploaded object, and returns the version ID as the x-oss-version-id field in the response header. In a versioning-suspended bucket, the version ID added to an upload object is null. If you upload an object with the same name as an existing object to a versioning-suspended bucket, the existing object is overwritten. In this case, each object only has one version of which the ID is null.

The following code provides an example for simple upload:

using System.Text;
using Aliyun.OSS;
var endpoint = "<yourEndpoint>";
var accessKeyId = "<yourAccessKeyId>";
var accessKeySecret = "<yourAccessKeySecret>";
var bucketName = "<yourBucketName>";
var objectName = "<yourObjectName>";
var objectContent = "More than just cloud." ;
// Create an OSSClient instance.
var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
try
{
    byte[] binaryData = Encoding.ASCII.GetBytes(objectContent);
    MemoryStream requestContent = new MemoryStream(binaryData);
    // Upload the object.
    var result = client.PutObject(bucketName, objectName, requestContent);
    Console.WriteLine("Put object succeeded versionid : {0}", result.VersionId);
}
catch (Exception ex)
{
    Console.WriteLine("Put object failed, {0}", ex.Message);
}

For more information about simple upload, see PutObject.

Append upload

In a versioning-enabled bucket, the AppendObject operation can be performed only on objects of which the current version is an appendable object.
Note
  • When you perform the AppendObject operation on an object of which the current version is an appendable object, OSS does not generate a previous version for the appendable object.
  • When you perform the PutObject or DeleteObject operation on an object of which the current version is an appendable object, OSS stores the appendable object as a previous version and prevents the object from being further appended.
  • You cannot perform the AppendObject operation on objects of which the current version is not an appendable object such as a normal object or a delete marker.

The following code provides an example for append upload:

using Aliyun.OSS;
var endpoint = "<yourEndpoint>";
var accessKeyId = "<yourAccessKeyId>";
var accessKeySecret = "<yourAccessKeySecret>";
var bucketName = "<yourBucketName>";
var objectName = "<yourObjectName>";
var localFilename = "<yourLocalFilename>";
// Create an OSSClient instance.
var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
// If this is the first time an object is appended, the append position is 0. The returned value is the position for the next append. The position to start the next append is the total length of appended bytes and the append object.
long position = 0;
try
{
    var metadata = client.GetObjectMetadata(bucketName, objectName);
    position = metadata.ContentLength;
}
catch (Exception) { }
try
{
    using (var fs = File.Open(localFilename, FileMode.Open))
    {
        var request = new AppendObjectRequest(bucketName, objectName)
        {
            ObjectMetadata = new ObjectMetadata(),
            Content = fs,
            Position = position
        };
        // Append the object.
        var result = client.AppendObject(request);
        // Configure the position where the object is appended based on the previous object length.
        position = result.NextAppendPosition;
        Console.WriteLine("Append object succeeded, next append position:{0}, vesionid:{1}", position, result.VersionId);
    }
    // Query the position for the next append and start the next append.
    using (var fs = File.Open(localFilename, FileMode.Open))
    {
        var request = new AppendObjectRequest(bucketName, objectName)
        {
            ObjectMetadata = new ObjectMetadata(),
            Content = fs,
            Position = position
        };
        var result = client.AppendObject(request);
        position = result.NextAppendPosition;
        Console.WriteLine("Append object succeeded, next append position:{0}, vesionid:{1}", position, result.VersionId);
    }
}
catch (Exception ex)
{
    Console.WriteLine("Append object failed, {0}", ex.Message);
}

For more information about append upload, see AppendObject.

Multipart upload

If you call CompleteMultipartUpload to complete the MultipartUpload task for an object in a versioning-enabled bucket, OSS generates a unique version ID for the object and returns it as the x-oss-version-id field in the response header.

The following code provides an example for multipart upload:

using Aliyun.OSS;
var endpoint = "<yourEndpoint>";
var accessKeyId = "<yourAccessKeyId>";
var accessKeySecret = "<yourAccessKeySecret>";
var bucketName = "<yourBucketName>";
var objectName = "<yourObjectName>";
var localFilename = "<yourLocalFilename>";
// Create an OSSClient instance.
var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
// Initialize a multipart upload task.
var uploadId = "";
try
{
    // Specify the name of the object to upload and the bucket to which the object belongs. You can configure object metadata when you use InitiateMultipartUploadRequest without specifying the ContentLength parameter.
    var request = new InitiateMultipartUploadRequest(bucketName, objectName);
    var result = client.InitiateMultipartUpload(request);
    uploadId = result.UploadId;
    // Display the upload ID.
    Console.WriteLine("Init multi part upload succeeded");
    Console.WriteLine("Upload Id:{0}", result.UploadId);
}
catch (Exception ex)
{
    Console.WriteLine("Init multi part upload failed, {0}", ex.Message);
}
// Calculate the total number of parts.
var partSize = 100 * 1024;
var fi = new FileInfo(localFilename);
var fileSize = fi.Length;
var partCount = fileSize / partSize;
if (fileSize % partSize ! = 0)
{
    partCount++;
}
// Start the multipart upload task. partETags is a list of part ETags. OSS verifies the validity of each part after it receives the part list. After all parts are verified, OSS combines these parts into a complete object.
var partETags = new List<PartETag>();
try
{
    using (var fs = File.Open(localFilename, FileMode.Open))
    {
        for (var i = 0; i < partCount; i++)
        {
            var skipBytes = (long)partSize * i;
            // Find the start position of the upload.
            fs.Seek(skipBytes, 0);
            // Calculate the size of the part to upload. The size of the last part is the size of the remaining data.
            var size = (partSize < fileSize - skipBytes) ? partSize : (fileSize - skipBytes);
            var request = new UploadPartRequest(bucketName, objectName, uploadId)
            {
                InputStream = fs,
                PartSize = size,
                PartNumber = i + 1
            };
            // Call the UploadPart operation to perform part upload. The returned results contain the value of the part ETag.
            var result = client.UploadPart(request);
            partETags.Add(result.PartETag);
            Console.WriteLine("finish {0}/{1}", partETags.Count, partCount);
        }
        Console.WriteLine("Put multi part upload succeeded");
    }
}
catch (Exception ex)
{
    Console.WriteLine("Put multi part upload failed, {0}", ex.Message);
}
// Complete the multipart upload task.
try
{
    var completeMultipartUploadRequest = new CompleteMultipartUploadRequest(bucketName, objectName, uploadId);
    foreach (var partETag in partETags)
    {
        completeMultipartUploadRequest.PartETags.Add(partETag);
    }
    var result = client.CompleteMultipartUpload(completeMultipartUploadRequest);
    Console.WriteLine("CompleteMultipartUpload succeeded, vesionid:{0}", result.VersionId);
}
catch (Exception ex)
{
    Console.WriteLine("complete multi part failed, {0}", ex.Message);
}

For more information about multipart upload, see CompleteMultipartUpload.