Means.Client 0.1.2

dotnet add package Means.Client --version 0.1.2
                    
NuGet\Install-Package Means.Client -Version 0.1.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Means.Client" Version="0.1.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Means.Client" Version="0.1.2" />
                    
Directory.Packages.props
<PackageReference Include="Means.Client" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Means.Client --version 0.1.2
                    
#r "nuget: Means.Client, 0.1.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Means.Client@0.1.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Means.Client&version=0.1.2
                    
Install as a Cake Addin
#tool nuget:?package=Means.Client&version=0.1.2
                    
Install as a Cake Tool

Means C# SDK

Standalone C# SDK for the Means S3-compatible object storage API. The package targets net8.0 and netstandard2.1, uses HttpClient, signs requests with SigV4, parses S3-style XML responses, and throws MeansError for S3-style XML errors.

Install from source

dotnet build SDKs/csharp/Means.Client.csproj -c Release
# or
dotnet pack SDKs/csharp/Means.Client.csproj -c Release

Release 构建或打包会在 SDKs/csharp/bin/Release 生成 Means.Client.0.1.2.nupkg 和 Means.Client.0.1.2.snupkg。 Reference the generated Means.Client package or project from your application.

Basic usage

For a runnable end-to-end sample, see ../examples/csharp-basic. It covers bucket creation, object upload/download, presigned GET/PUT URLs, versioning, lifecycle, and multipart upload.

using Means;

var client = new MeansClient(new MeansClientOptions
{
    Endpoint = new Uri("http://localhost:5000"),
    Credentials = new MeansCredentials("access-key", "secret-key"),
    Region = "us-east-1",
    ForcePathStyle = true
});

await client.CreateBucketAsync("photos");

await using var upload = File.OpenRead("image.jpg");
await client.PutObjectAsync(
    "photos",
    "2026/image.jpg",
    upload,
    contentType: "image/jpeg",
    metadata: new Dictionary<string, string> { ["origin"] = "camera" });

var objects = await client.ListObjectsAsync("photos", prefix: "2026/");

await using var download = await client.GetObjectAsync("photos", "2026/image.jpg");
await using var file = File.Create("downloaded.jpg");
await download.Content.CopyToAsync(file);

API surface

  • MeansClient
  • MeansClientOptions
  • MeansCredentials
  • BucketSummary
  • ObjectSummary
  • BucketVersioningResult
  • ListObjectVersionsResult
  • BucketLifecycleConfiguration
  • ObjectHeadResult
  • PutObjectResult
  • DeleteObjectResult
  • CopyObjectResult
  • CopyObjectOptions
  • ObjectTaggingResult
  • BucketXmlConfigurationResult
  • MultipartUploadResult
  • UploadPartResult
  • CopyPartResult
  • CompleteMultipartUploadResult
  • ListPartsResult
  • ListMultipartUploadsResult
  • ListMultipartUploadsOptions
  • PresignedRequest
  • MeansError

MeansClient exposes PascalCase async methods for S3-compatible operations:

  • ListBucketsAsync
  • CreateBucketAsync
  • HeadBucketAsync
  • DeleteBucketAsync
  • GetBucketVersioningAsync
  • SetBucketVersioningAsync
  • ListObjectVersionsAsync
  • GetBucketLifecycleAsync
  • PutBucketLifecycleAsync
  • DeleteBucketLifecycleAsync
  • GetBucketCorsAsync
  • PutBucketCorsAsync
  • DeleteBucketCorsAsync
  • GetBucketNotificationAsync
  • PutBucketNotificationAsync
  • DeleteBucketNotificationAsync
  • ListObjectsAsync
  • PutObjectAsync
  • GetObjectAsync
  • HeadObjectAsync
  • DeleteObjectAsync
  • CopyObjectAsync
  • GetObjectTaggingAsync
  • PutObjectTaggingAsync
  • DeleteObjectTaggingAsync
  • InitiateMultipartUploadAsync
  • UploadPartAsync
  • UploadPartCopyAsync
  • CompleteMultipartUploadAsync
  • AbortMultipartUploadAsync
  • ListPartsAsync
  • ListMultipartUploadsAsync
  • UploadObjectMultipartAsync
  • CreatePresignedGetUrlAsync
  • CreatePresignedPutUrlAsync
  • CreatePresignedUploadPartUrlAsync

Synchronous presign helpers are also available as CreatePresignedGetUrl, CreatePresignedPutUrl, and CreatePresignedUploadPartUrl because URL signing does not perform I/O.

Multipart upload

await using var largeFile = File.OpenRead("large-video.mp4");
var completed = await client.UploadObjectMultipartAsync(
    "photos",
    "video/large-video.mp4",
    largeFile,
    contentType: "video/mp4");

Console.WriteLine(completed.ETag);

The high-level helper requires a readable, seekable stream, uses 16 MiB parts by default, and aborts the upload if a part or completion fails. Low-level multipart methods are available when callers need custom scheduling, UploadPartCopy, pagination, or presigned part URLs.

Versioning and lifecycle

await client.SetBucketVersioningAsync("photos", "Enabled");
var versions = await client.ListObjectVersionsAsync("photos", prefix: "2026/");
await using var oldVersion = await client.GetObjectAsync("photos", "2026/image.jpg", versions.Versions[0].VersionId);

await client.PutBucketLifecycleAsync("photos", new BucketLifecycleConfiguration
{
    Rules =
    {
        new LifecycleRule
        {
            Id = "expire-logs",
            Status = "Enabled",
            Prefix = "logs/",
            ExpirationDays = 30,
            NoncurrentVersionExpirationDays = 7,
            AbortIncompleteMultipartUploadDays = 1
        }
    }
});

Lifecycle day values must be positive integers. Empty lifecycle configurations are rejected; use DeleteBucketLifecycleAsync to remove rules.

Tagging, CORS, and notification

await client.PutObjectTaggingAsync(
    "photos",
    "2026/image.jpg",
    new Dictionary<string, string> { ["kind"] = "raw" });

var tags = await client.GetObjectTaggingAsync("photos", "2026/image.jpg");

await client.PutBucketCorsAsync(
    "photos",
    "<CORSConfiguration><CORSRule><AllowedOrigin>*</AllowedOrigin><AllowedMethod>GET</AllowedMethod></CORSRule></CORSConfiguration>");

Bucket CORS and notification methods use raw XML so callers can pass through S3-compatible configuration variants without waiting for SDK model updates.

Presigned URLs

var presignedGet = client.CreatePresignedGetUrl(
    "photos",
    "2026/image.jpg",
    TimeSpan.FromMinutes(15));

var versionedGet = client.CreatePresignedGetUrl(
    "photos",
    "2026/image.jpg",
    versionId: "object-version-id",
    expires: TimeSpan.FromMinutes(15));

Console.WriteLine(presignedGet.Url);

SigV4 presigned URLs require credentials and support expirations up to seven days.

Error handling

Means returns S3-style XML error envelopes. Non-success responses throw MeansError:

try
{
    await client.HeadObjectAsync("photos", "missing.jpg");
}
catch (MeansError error) when (error.Code == "NoSuchKey")
{
    Console.WriteLine(error.RequestId);
}

Addressing

Path-style addressing is enabled by default:

https://api.means.local/bucket/key

Set ForcePathStyle = false to use virtual-hosted-style addressing for DNS-compatible endpoints:

https://bucket.means.local/key

For the common Means layout where path-style requests go to api.means.local and virtual-hosted requests go to bucket.means.local, the SDK infers the suffix automatically. You can also set it explicitly:

ForcePathStyle = false,
VirtualHostedDomainSuffix = "means.local"
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.1

    • No dependencies.
  • net8.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.2 136 6/5/2026
0.1.0 175 5/9/2026