Updated on 2025-12-01 GMT+08:00
C#
Sample code of multipart upload using C#:
using System.Net;
using System.Net.Http.Headers;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Xml.Linq;
using HuaweiCloud.SDK.Core;
using HuaweiCloud.SDK.Core.Auth;
using HuaweiCloud.SDK.Vod.V1;
using HuaweiCloud.SDK.Vod.V1.Model;
/**
* Example of multipart upload
*/
public class PartUploadDemo
{
// Set the buffer size as needed, that is, the size of the file part read each time.
private const int BuffSize = 1024 * 1024; // 1MB
// Region
private const string RegionNorth4 = "cn-north-4";
private const string RegionNorth1 = "cn-north-1";
private const string RegionEast2 = "cn-east-2";
// AK/SK
private const string Ak = "";
private const string Sk = "";
public static void Start()
{
// Path of the local media asset to be uploaded
const string filePath = "";
// Upload the media asset.
UploadFile(filePath);
}
/**
* Multipart upload
* @param filePath: local path where the file to be uploaded is
*/
private static void UploadFile(string filePath)
{
// Verify the file and its path.
ValidFile(filePath);
var fileInfo = new FileInfo(filePath);
try
{
// An MP4 file is used as an example. For details about other formats, see the official website.
var fileType = "MP4";
var fileContentType = "video/mp4";
// 1. Initialize authentication and obtain vodClient.
var vodClient = CreateVodClient();
Console.WriteLine("Start to create a media asset:" + fileInfo.Name);
// 2. Create a VOD media asset.
var assetResponse = CreateAssetByFileUpload(vodClient, fileInfo.Name, fileInfo.Name, fileType);
// 3. Obtain authorization for initializing an upload task.
var initAuthResponse = InitPartUploadAuthority(vodClient, assetResponse, fileContentType);
// 4. Initialize the upload task.
var uploadId = InitPartUpload(initAuthResponse.SignStr, fileContentType).Result;
// Count the number of file parts.
var partNumber = 1;
// Record the read length.
var bytesRead = 0;
// 7. Read the file content and repeat steps 5 and 6 to upload all parts.
var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
// Create a buffer.
var buffer = new byte[BuffSize];
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0)
{
// If the read length is less than the buffer length, copy the data within the valid length and apply the data to the last part.
if (bytesRead != BuffSize)
{
var tmp = new byte[bytesRead];
Array.Copy(buffer, tmp, bytesRead);
buffer = tmp;
}
// Calculate an MD5 hash value.
var hashBytes = MD5.HashData(buffer);
// Convert the MD5 hash value to a Base64 string.
var contentMd5 = Convert.ToBase64String(hashBytes);
// Output the Base64 string.
Console.WriteLine("The MD5 value of the "+(partNumber)+" part in the file is " + contentMd5);
// 5. Obtain authorization for multipart upload.
var partUploadAuthorityResponse =
GetPartUploadAuthority(vodClient, fileContentType, assetResponse, contentMd5, uploadId, partNumber);
// 6. Upload parts.
var flag = UploadPartFile(partUploadAuthorityResponse.SignStr, buffer, contentMd5).Result;
// The part number automatically increments by one.
partNumber++;
}
fileStream.Close();
// 8. Obtain authorization for obtaining uploaded parts.
var listPartUploadAuthorityResponse = ListUploadedPartAuthority(vodClient, assetResponse, uploadId);
// 9. Obtain uploaded parts.
var partInfo = ListUploadedPart(listPartUploadAuthorityResponse.SignStr).Result;
// 10. Obtain authorization for merging parts.
var mergePartUploadAuthorityResponse = MergeUploadedPartAuthority(vodClient, assetResponse, uploadId);
// 11. Merge uploaded parts.
_ = MergeUploadedPart(mergePartUploadAuthorityResponse.SignStr, partInfo).Result;
// 12. Confirm the media asset upload.
ConfirmUploaded(vodClient, assetResponse);
Console.WriteLine("Media asset created. assetId: " + assetResponse.AssetId");
}
catch (RequestTimeoutException requestTimeoutException)
{
Console.WriteLine(requestTimeoutException.ErrorMessage);
}
catch (ServiceResponseException clientRequestException)
{
Console.WriteLine(clientRequestException.HttpStatusCode);
Console.WriteLine(clientRequestException.RequestId);
Console.WriteLine(clientRequestException.ErrorCode);
Console.WriteLine(clientRequestException.ErrorMessage);
}
catch (ConnectionException connectionException)
{
Console.WriteLine(connectionException.ErrorMessage);
}
catch (Exception exception)
{
Console.WriteLine(exception.Message);
}
}
/**
* Verify the file and its path.
* @param filePath
*/
private static void ValidFile(string filePath)
{
var fileExists = File.Exists(filePath);
if (!fileExists)
{
// File not found.
throw new Exception("File not found.");
}
}
/**
* 1. Construct authentication.
* @return
*/
private static VodClient CreateVodClient()
{
var config = HttpConfig.GetDefaultConfig();
config.IgnoreSslVerification = true;
var auth = new BasicCredentials(Ak, Sk);
var client = VodClient.NewBuilder()
.WithCredential(auth)
.WithRegion(VodRegion.ValueOf(RegionNorth4))
.WithHttpConfig(config)
.Build();
return client;
}
/**
* 2. Create a media asset.
* @param client
* @param title
* @param videoName
* @param video
* @return
*/
private static CreateAssetByFileUploadResponse CreateAssetByFileUpload(VodClient client, string title,
string videoName,
string videoType)
{
Console.WriteLine("createAssetByFileUpload start");
var req = new CreateAssetByFileUploadRequest
{
Body = new CreateAssetByFileUploadReq()
{
Title = title,
VideoName = videoName,
VideoType = videoType
}
};
// Call the API for creating a media asset.
var response = client.CreateAssetByFileUpload(req);
Console.WriteLine("createAssetByFileUpload end; createAssetResponse:" + response);
return response;
}
/**
* 3. Obtain authorization for initializing an upload task.
* @param client
* @param assetResponse
* @param fileContentType
*/
private static ShowAssetTempAuthorityResponse InitPartUploadAuthority(VodClient client,
CreateAssetByFileUploadResponse assetResponse,
string fileContentType)
{
Console.WriteLine("Obtain authorization for initializing an upload task. initPartUploadAuthority start");
// Configure parameters.
var request = new ShowAssetTempAuthorityRequest
{
HttpVerb = "POST",
Bucket = assetResponse.Target.Bucket,
ObjectKey = assetResponse.Target.Object,
ContentType = fileContentType
};
// Send an initialization request.
var response = client.ShowAssetTempAuthority(request);
Console.WriteLine("Obtain authorization for initializing an upload task. initPartUploadAuthority end; response" + response);
return response;
}
/**
* 4. Initialize multipart upload.
* @param signStr
* @param contentType
* @return
*/
private static async Task<string?> InitPartUpload(string signStr, string contentType)
{
Console.WriteLine("Initialize multipart upload. initPartUpload start");
using var client = new HttpClient();
var content = new ByteArrayContent([]);
content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
var response = await client.PostAsync(signStr, content);
// Ensure that the request is successful.
response.EnsureSuccessStatusCode();
var responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseBody);
var root = XElement.Parse(responseBody);
var ns = root.Name.Namespace;
var uploadId = root.Element("{" + ns + "}UploadId")?.Value;
Console.WriteLine("Initialize multipart upload. initPartUpload end; UploadId:" + uploadId);
return uploadId;
}
/**
* 5. Obtain authorization for multipart upload.
* @param client
* @param fileContentType
* @param assetResponse
* @param contentMd5
* @param uploadId
* @param partNumber
* @return
*/
private static ShowAssetTempAuthorityResponse GetPartUploadAuthority(VodClient client,
string fileContentType, CreateAssetByFileUploadResponse assetResponse, string contentMd5,
string uploadId, int partNumber)
{
// Thread.Sleep(2000);
Console.WriteLine ("Obtain authorization for multipart upload. GetPartUploadAuthority start:" + partNumber);
// Configure parameters.
var request = new ShowAssetTempAuthorityRequest
{
HttpVerb = "PUT",
Bucket = assetResponse.Target.Bucket,
ObjectKey = assetResponse.Target.Object,
ContentType = fileContentType,
// ContentMd5 = contentMd5,
ContentMd5 = HttpUtility.UrlEncode(contentMd5),
UploadId = uploadId,
PartNumber = partNumber
};
Console.WriteLine(WebUtility.UrlEncode(contentMd5));
var response = client.ShowAssetTempAuthority(request);
Console.WriteLine ("Obtain authorization for multipart upload. GetPartUploadAuthority end; response" + partNumber + "; response: " + response + "\n");
return response;
}
/**
* 6. Upload parts.
* @param signStr
* @param fileByte
* @param contentMd5
*/
public static async Task<Boolean> UploadPartFile(string signStr, byte[] fileByte, string contentMd5)
{
Console.WriteLine("Upload parts. uploadPartFile start");
HttpClient client = new HttpClient();
HttpContent content = new ByteArrayContent(fileByte);
content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
content.Headers.Add("Content-MD5", contentMd5);
HttpResponseMessage response = await client.PutAsync(signStr, content);
Console.WriteLine("Upload parts. response:" + response);
response.EnsureSuccessStatusCode(); // Ensure that the request is successful.
var responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine("Upload parts. uploadPartFile end; response:" + responseBody);
return true;
}
/**
* 8. Obtain authorization for listing uploaded parts.
* @param client
* @param assetResponse
* @param uploadId
* @return
*/
private static ShowAssetTempAuthorityResponse ListUploadedPartAuthority(VodClient client,
CreateAssetByFileUploadResponse assetResponse, string? uploadId)
{
Console.WriteLine("Obtain authorization for listing uploaded parts. listUploadedPartAuthority start");
var request = new ShowAssetTempAuthorityRequest
{
HttpVerb = "GET",
Bucket = assetResponse.Target.Bucket,
ObjectKey = assetResponse.Target.Object,
UploadId = uploadId
};
var response = client.ShowAssetTempAuthority(request);
Console.WriteLine("Obtain authorization for listing uploaded parts. listUploadedPartAuthority end; response: " + response);
return response;
}
/**
* 9. Query uploaded parts.
* @param signStr
* @return
*/
private static async Task<string> ListUploadedPart(string signStr)
{
Console.WriteLine("Query uploaded parts. listUploadedPart start");
var partNumberMarker = 0;
var mergerRoot = new XElement("CompleteMultipartUpload");
while (true)
{
// List parts.
using var client = new HttpClient();
var response = await client.GetAsync(signStr + "&part-number-marker=" + partNumberMarker);
response.EnsureSuccessStatusCode();
var responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseBody);
var root = XElement.Parse(responseBody);
var ns = root.Name.Namespace;
var partNodes = root.Elements("{" + ns + "}Part");
var partNumberMarkerElement = root.Element("{" + ns + "}NextPartNumberMarker");
foreach (var partNode in partNodes)
{
var partNumberNode = partNode.Element("{" + ns + "}PartNumber");
var partNumber = partNumberNode?.Value;
var eTagNode = partNode.Element("{" + ns + "}ETag");
var etag = eTagNode?.Value;
var part = new XElement("Part");
mergerRoot.Add(part);
part.Add(new XElement("PartNumber", partNumber));
part.Add(new XElement("ETag", etag));
}
partNumberMarker = Convert.ToInt32(partNumberMarkerElement?.Value);
if (partNumberMarker == 0 || partNumberMarker % 1000 != 0)
{
break;
}
}
Console.WriteLine(mergerRoot.ToString());
Console.WriteLine("Query uploaded parts. listUploadedPart end");
return mergerRoot.ToString();
}
/**
* 10. Obtain authorization for merging parts.
* @param client
* @param assetResponse
* @param uploadId
* @return
*/
private static ShowAssetTempAuthorityResponse MergeUploadedPartAuthority(VodClient client,
CreateAssetByFileUploadResponse assetResponse, string? uploadId)
{
Console.WriteLine("Obtain authorization for merging parts. mergeUploadedPartAuthority start");
var request = new ShowAssetTempAuthorityRequest
{
HttpVerb = "POST",
Bucket = assetResponse.Target.Bucket,
ObjectKey = assetResponse.Target.Object,
UploadId = uploadId
};
var response = client.ShowAssetTempAuthority(request);
Console.WriteLine("Obtain authorization for merging parts. mergeUploadedPartAuthority end; response: " + response);
return response;
}
/**
* 11. Merge parts.
*/
public static async Task<Boolean> MergeUploadedPart(string signStr, string partInfo)
{
Console.WriteLine("Merge parts. mergeUploadedPart start");
using var client = new HttpClient();
// Add content-Type to the request header and set the value to application/xml.
HttpContent content = new StringContent(partInfo);
content.Headers.ContentType = new MediaTypeHeaderValue("application/xml");
var response = await client.PostAsync(signStr, content);
var responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseBody);
response.EnsureSuccessStatusCode();
Console.WriteLine("Merge parts. mergeUploadedPart end");
return true;
}
/**
* Confirm the upload completion.
*/
private static void ConfirmUploaded(VodClient client, CreateAssetByFileUploadResponse assetResponse)
{
Console.WriteLine("Confirm the upload completion. confirmUploaded start");
var request = new ConfirmAssetUploadRequest
{
Body = new ConfirmAssetUploadReq()
{
Status = ConfirmAssetUploadReq.StatusEnum.FromValue("CREATED"),
AssetId = assetResponse.AssetId
}
};
var response = client.ConfirmAssetUpload(request);
Console.WriteLine("Upload completed. assetId: " + response);
}
}
Parent topic: Sample Code for Multipart Upload
Feedback
Was this page helpful?
Provide feedbackThank you very much for your feedback. We will continue working to improve the documentation.See the reply and handling status in My Cloud VOC.
The system is busy. Please try again later.
For any further questions, feel free to contact us through the chatbot.
Chatbot