Skip to main content

Overview

NuGet Version GitHub

The CloudBase C# SDK enables you to use CloudBase capabilities in .NET applications (including Unity, .NET Core, console, and server-side apps), covering authentication, document databases, data models, MySQL databases, Cloud Functions, CloudBase Run, APIs, Cloud Storage, and more.

The SDK is open-sourced on GitHub. Feel free to browse the source code, examples, and report issues: TencentCloudBase/cloudbase-csharp-sdk.

Note

CloudBase C# SDK is fully aligned with the HTTP API. All asynchronous methods end with Async and return Task<T>.

The SDK is organized into the following categories by functionality:

  • Installation: Installation via NuGet, Unity (UPM), and source reference.
  • Example Projects: Quick start, terminal testing tool, and Unity game examples under the repository's examples directory.
  • Dependency Injection: Register the SDK via AddCloudBase in scenarios such as ASP.NET Core.
  • Authentication: API methods for user registration and login, supporting multiple login methods.
  • Session Management: API methods for managing user session state and tokens.
  • User Management: API methods for retrieving, updating, and managing user information.
  • Identity Source Management: API methods for managing third-party identity source binding and unbinding.
  • Password Management: API methods related to password reset and modification.
  • Verification Management: API methods for sending, verifying, and resending verification codes, as well as creating, verifying, and managing graphical CAPTCHAs.
  • Document Database: Chained operations for collections, documents, queries, aggregations, and transactions in document (NoSQL) databases.
  • Data Models: CRUD operations for data models.
  • Data Source Query: Query data source aggregation lists, details, schemas, and table names.
  • MySQL Database: MySQL RESTful database operations.
  • Cloud Functions: Invoke Cloud Functions and function-style CloudBase Run.
  • CloudBase Run: Invoke CloudBase Run container services.
  • APIs: Invoke APIs.
  • Cloud Storage: File upload, download, deletion, copy, and move operations.
  • Changelog: Change records for each version.

Installation

It is recommended to install via NuGet:

dotnet add package Tencent.CloudBase

Or add a reference in .csproj:

<ItemGroup>
<PackageReference Include="Tencent.CloudBase" Version="1.0.0" />
</ItemGroup>

The net10.0 target (with DI integration) is automatically selected.


Example Projects

The repository's examples directory provides three complete, ready-to-run examples covering different usage scenarios from console to Unity:

ExampleTypeDescription
QuickStart.NET ConsoleA minimal quick start example demonstrating core flows such as initialization, anonymous login, and retrieving user information.
TerminalUI.NET Interactive TerminalAn interactive testing tool based on Spectre.Console, with a menu to experience authentication, Cloud Functions, data models, MySQL, Cloud Storage, document databases, and other capabilities item by item.
UnityGameUnity ProjectA complete mini-game project that can be opened with Unity Hub and run by pressing Play. It demonstrates integrating login, data models, document databases, Cloud Storage, and Cloud Functions in Unity and rendering to the UI.

A minimal console example demonstrating initialization, anonymous login, and retrieving user information.

# Run after setting environment variables
export CLOUDBASE_ENV=your-env-id
export CLOUDBASE_ACCESS_KEY=your-publishable-key # Optional, for anonymous access

dotnet run --project examples/QuickStart

Basic Usage Example

accessKey can be generated at CloudBase Platform / API Key Configuration

using CloudBase;

// Initialization (asynchronous static factory)
var app = await CloudBase.InitAsync(
env: "your-env-id", // Replace with your environment ID
region: "ap-shanghai", // Region, defaults to Shanghai
accessKey: "your-key", // Fill in the generated Publishable Key
authConfig: new AuthConfig
{
DetectSessionInUrl = true // Optional: automatically detect OAuth parameters in the URL
}
);

var auth = app.Auth;

Full parameters of InitAsync:

ParameterTypeDefaultDescription
envstringRequiredTCB environment ID
regionstringap-shanghaiRegion
langstringzh-CNLanguage
accessKeystring?nullPublishable Key, used for anonymous access
authConfigAuthConfig?nullAuthentication configuration (e.g. DetectSessionInUrl)
captchaConfigCaptchaConfig?nullCAPTCHA configuration (e.g. OnCaptchaRequired callback)
storeIKeyValueStore?nullKey-value store implementation; uses the default file store when null. For server-side multi-tenant scenarios, injecting a custom implementation is recommended
httpClientHttpClient?nullCustom HttpClient (not available on WebGL)
transportIHttpTransport?nullCustom HTTP transport layer
intlboolfalseWhether it is the international site

After initialization, you can access each module via app.Auth, app.Storage, app.MySql, app.Apis, app.Functions, app.CloudRun, app.Models, app.Database(...). When done, call app.Dispose() to release the underlying HttpClient (in DI scenarios, the container manages this automatically; no manual disposal is needed).


Dependency Injection

In ASP.NET Core / Blazor Server / Worker and other scenarios based on Microsoft.Extensions.DependencyInjection, you can register the SDK with the DI container via the AddCloudBase extension method. Internally, it reuses the connection pool through IHttpClientFactory, and the CloudBase instance is initialized as a singleton with lazy loading (initialized only once).

note

This capability is only available under the .NET (net10.0) target.

AddCloudBase

IServiceCollection services.AddCloudBase(Action<CloudBaseOptions> configure)

Registers CloudBase into the dependency injection container. Since CloudBase.InitAsync is an asynchronous factory and cannot be constructed directly by DI, what is registered is an accessor ICloudBaseAccessor that asynchronously retrieves the instance on demand via GetAsync().

Parameters

configure
Action<CloudBaseOptions>

Configuration delegate

Response

IServiceCollection
IServiceCollection

Service collection (for fluent chaining)

Example

using CloudBase.DependencyInjection;

// Program.cs
builder.Services.AddCloudBase(options =>
{
options.Env = "your-env-id";
options.Region = "ap-shanghai";
options.AccessKey = "your-key"; // Optional, for anonymous access
});

Authentication Sign-up

SignUpAsync

Task<CloudBaseResponse<SignUpResData>> auth.SignUpAsync(SignUpReq @params)

Registers a new user account using the smart sign-up and sign-in flow.

  • Creates a new user account
  • Uses the smart sign-up and sign-in flow: send verification code → wait for user input → intelligently determine user existence → automatically sign in or sign up and sign in
  • If the user already exists, sign in directly; if the user does not exist, register a new user and automatically sign in

Parameters

@params
SignUpReq

Response

Task
CloudBaseResponse<SignUpResData>

Example

var result = await auth.SignUpAsync(new SignUpReq
{
Email = "user@example.com",
Password = "securePassword123",
Nickname = "NewUser",
});

if (result.Error != null)
{
Console.WriteLine($"Sign-up failed: {result.Error.Message}");
return;
}

// Verification code verification
var verifyResult = await result.Data!.VerifyOtp!(
new VerifyOtpParams { Token = "123456" }
);

if (verifyResult.IsSuccess)
{
Console.WriteLine($"Sign-up succeeded: {verifyResult.Data?.User?.Id}");
}

SignInAnonymouslyAsync

Task<CloudBaseResponse<SignInResData>> auth.SignInAnonymouslyAsync(string? providerToken = null)

Anonymous sign-in. Creates a temporary account without requiring the user to provide any credentials.

Parameters

providerToken
string?

Optional third-party provider token

Response

Task
CloudBaseResponse<SignInResData>

Example

var result = await auth.SignInAnonymouslyAsync();

if (result.IsSuccess)
{
Console.WriteLine($"Anonymous sign-in succeeded: {result.Data?.User?.Id}");
}
else
{
Console.WriteLine($"Anonymous sign-in failed: {result.Error?.Message}");
}

SignInWithPasswordAsync

Task<CloudBaseResponse<SignInResData>> auth.SignInWithPasswordAsync(SignInWithPasswordReq @params)

Sign in with a username (or email, phone number) and password.

Parameters

@params
SignInWithPasswordReq

Response

Task
CloudBaseResponse<SignInResData>

Example

var result = await auth.SignInWithPasswordAsync(new SignInWithPasswordReq
{
Username = "user@example.com",
Password = "securePassword123",
});

if (result.IsSuccess)
{
Console.WriteLine($"Sign-in succeeded: {result.Data?.User?.Id}");
}
else
{
Console.WriteLine($"Sign-in failed: {result.Error?.Message}");
}

SignInWithUsernameAsync

Task<CloudBaseResponse<SignInResData>> auth.SignInWithUsernameAsync(
VerificationInfo verificationInfo,
string verificationCode,
string username,
string? loginType = null,
Dictionary<string, object?>? bindInfo = null)

Sign in with a username (or email, phone number) together with a verification code. verificationInfo is obtained from GetVerificationAsync, and verificationCode is the verification code entered by the user.

Parameters

verificationInfo
VerificationInfo

Verification information (returned by GetVerificationAsync)

verificationCode
string

Verification code

username
string

Username / email / phone number

loginType
string?

Login type (optional)

bindInfo
Dictionary<string, object?>?

Binding information (optional)

Response

Task
CloudBaseResponse<SignInResData>

Example

// 1. First get the verification information (send the verification code)
var verifyRes = await auth.GetVerificationAsync(new GetVerificationReq
{
Username = "user@example.com",
});

if (verifyRes.Error != null)
{
Console.WriteLine($"Failed to get verification information: {verifyRes.Error.Message}");
return;
}

// 2. Sign in with the verification information and the user-entered verification code
var result = await auth.SignInWithUsernameAsync(
verificationInfo: verifyRes.Data!.VerificationInfo!,
verificationCode: "123456",
username: "user@example.com"
);

if (result.IsSuccess)
{
Console.WriteLine($"Sign-in succeeded: {result.Data?.User?.Id}");
}
else
{
Console.WriteLine($"Sign-in failed: {result.Error?.Message}");
}

SignInWithOtpAsync

Task<CloudBaseResponse<SignInWithOtpResData>> auth.SignInWithOtpAsync(SignInWithOtpReq @params)

Sign in with a one-time password (OTP). After sending the verification code, complete verification via the VerifyOtp callback in the returned data.

Parameters

@params
SignInWithOtpReq

Response

Task
CloudBaseResponse<SignInWithOtpResData>

Example

var result = await auth.SignInWithOtpAsync(new SignInWithOtpReq
{
Email = "user@example.com",
});

if (result.Error != null)
{
Console.WriteLine($"Failed to send verification code: {result.Error.Message}");
return;
}

var verifyResult = await result.Data!.VerifyOtp!(
new VerifyOtpParams { Token = "123456" }
);

if (verifyResult.IsSuccess)
{
Console.WriteLine($"Sign-in succeeded: {verifyResult.Data?.User?.Id}");
}

SignInWithOAuthAsync

Task<CloudBaseResponse<SignInOAuthResData>> auth.SignInWithOAuthAsync(SignInWithOAuthReq @params)

Sign in with a third-party OAuth provider (such as WeChat, GitHub, etc.).

Parameters

@params
SignInWithOAuthReq

Response

Task
CloudBaseResponse<SignInOAuthResData>

Example

var result = await auth.SignInWithOAuthAsync(new SignInWithOAuthReq
{
Provider = "wechat",
RedirectTo = "https://your-app.com/callback",
});

if (result.IsSuccess)
{
Console.WriteLine($"Please redirect to the authorization URL: {result.Data?.Url}");
}

SignInWithIdTokenAsync

Task<CloudBaseResponse<SignInResData>> auth.SignInWithIdTokenAsync(SignInWithIdTokenReq @params)

Sign in with a third-party ID Token.

Parameters

@params
SignInWithIdTokenReq

Response

Task
CloudBaseResponse<SignInResData>

Example

var result = await auth.SignInWithIdTokenAsync(new SignInWithIdTokenReq
{
IdToken = "your-id-token",
Provider = "google",
});

if (result.IsSuccess)
{
Console.WriteLine($"Sign-in succeeded: {result.Data?.User?.Id}");
}

SignInWithCustomTicketAsync

Task<CloudBaseResponse<SignInResData>> auth.SignInWithCustomTicketAsync(Func<Task<string>> getTicketFn)

Sign in with a custom ticket. Pass in an asynchronous function to dynamically obtain the ticket.

Parameters

getTicketFn
Func<Task<string>>

Asynchronous function that returns a custom login ticket

Response

Task
CloudBaseResponse<SignInResData>

Example

var result = await auth.SignInWithCustomTicketAsync(async () =>
{
// Get the custom login ticket from your server
return await FetchTicketFromServerAsync();
});

if (result.IsSuccess)
{
Console.WriteLine($"Sign-in succeeded: {result.Data?.User?.Id}");
}

Session Management

GetSessionAsync

Task<CloudBaseResponse<SignInResData>> auth.GetSessionAsync()

Gets the current sign-in session information. If a valid session exists locally, that session is returned; otherwise Data.Session is null.

Parameters

No parameters

Response

Task
CloudBaseResponse<SignInResData>

Example

var result = await auth.GetSessionAsync();

if (result.Data?.Session != null)
{
Console.WriteLine($"User signed in: {result.Data.User?.Id}");
}
else
{
Console.WriteLine("User not signed in");
}

RefreshSessionAsync

Task<CloudBaseResponse<SignInResData>> auth.RefreshSessionAsync(string? refreshToken = null)

Refreshes the session token. You can pass a specified refresh token; if not provided, the refresh token of the current session is used.

Parameters

refreshToken
string?

Refresh token; if not provided, the current session token is used

Response

Task
CloudBaseResponse<SignInResData>

Example

var result = await auth.RefreshSessionAsync();

if (result.IsSuccess)
{
Console.WriteLine($"Session refreshed: {result.Data?.Session?.AccessToken}");
}

SetSessionAsync

Task<CloudBaseResponse<SignInResData>> auth.SetSessionAsync(SetSessionReq @params)

Manually sets the session (for example, restoring a session from the server side).

Parameters

@params
SetSessionReq

Response

Task
CloudBaseResponse<SignInResData>

Example

var result = await auth.SetSessionAsync(new SetSessionReq
{
AccessToken = "your-access-token",
RefreshToken = "your-refresh-token",
});

if (result.IsSuccess)
{
Console.WriteLine($"Session set: {result.Data?.User?.Id}");
}

SignOutAsync

Task<CloudBaseResponse<object?>> auth.SignOutAsync(SignOutReq? @params = null)

Signs out and clears the local session.

Parameters

@params
SignOutReq?

Sign-out parameters, optional

Response

Task
CloudBaseResponse<object?>

Example

var result = await auth.SignOutAsync();

if (result.IsSuccess)
{
Console.WriteLine("Signed out");
}

OnAuthStateChange

CloudBaseResponse<OnAuthStateChangeResultData> auth.OnAuthStateChange(OnAuthStateChangeCallback callback)

Listens for authentication state changes. The callback is triggered when the user signs in, signs out, or the token is refreshed. This is a synchronous method that returns an object you can use to unsubscribe.

Parameters

callback
OnAuthStateChangeCallback

State change callback, receives the event type and session data

Response

Return
CloudBaseResponse<OnAuthStateChangeResultData>

Example

var subscription = auth.OnAuthStateChange((eventType, session) =>
{
Console.WriteLine($"Auth state changed: {eventType}");
if (session != null)
{
Console.WriteLine($"Current user: {session.User?.Id}");
}
});

// Unsubscribe
subscription.Data?.Unsubscribe();

GetClaimsAsync

Task<CloudBaseResponse<GetClaimsResData>> auth.GetClaimsAsync()

Gets the JWT Claims information of the current user.

Parameters

No parameters

Response

Task
CloudBaseResponse<GetClaimsResData>

Example

var result = await auth.GetClaimsAsync();

if (result.IsSuccess)
{
Console.WriteLine($"Claims: {result.Data}");
}

User Management

GetUserAsync

Task<CloudBaseResponse<GetUserResData>> auth.GetUserAsync()

Gets the detailed information of the currently signed-in user.

Parameters

No parameters

Response

Task
CloudBaseResponse<GetUserResData>

Example

var result = await auth.GetUserAsync();

if (result.IsSuccess)
{
Console.WriteLine($"User ID: {result.Data?.User?.Id}");
Console.WriteLine($"Nickname: {result.Data?.User?.Nickname}");
}

RefreshUserAsync

Task<CloudBaseResponse<SignInResData>> auth.RefreshUserAsync()

Refreshes and re-fetches the current user information.

Parameters

No parameters

Response

Task
CloudBaseResponse<SignInResData>

Example

var result = await auth.RefreshUserAsync();

if (result.IsSuccess)
{
Console.WriteLine($"User refreshed: {result.Data?.User?.Nickname}");
}

UpdateUserAsync

Task<CloudBaseResponse<UpdateUserResData>> auth.UpdateUserAsync(UpdateUserReq @params)

Updates the profile information of the current user.

Parameters

@params
UpdateUserReq

Response

Task
CloudBaseResponse<UpdateUserResData>

Example

var result = await auth.UpdateUserAsync(new UpdateUserReq
{
Nickname = "New nickname",
AvatarUrl = "https://example.com/avatar.png",
});

if (result.IsSuccess)
{
Console.WriteLine("User profile updated");
}

DeleteUserAsync

Task<CloudBaseResponse<object?>> auth.DeleteUserAsync(DeleteUserReq @params)

Deletes (deactivates) the current user account.

Parameters

@params
DeleteUserReq

Delete user parameters

Response

Task
CloudBaseResponse<object?>

Example

var result = await auth.DeleteUserAsync(new DeleteUserReq());

if (result.IsSuccess)
{
Console.WriteLine("Account deleted");
}

Identity Provider Management

GetUserIdentitiesAsync

Task<CloudBaseResponse<GetUserIdentitiesResData>> auth.GetUserIdentitiesAsync()

Gets the list of identity providers bound to the current user.

Parameters

No parameters

Response

Task
CloudBaseResponse<GetUserIdentitiesResData>

Example

var result = await auth.GetUserIdentitiesAsync();

if (result.IsSuccess)
{
Console.WriteLine($"Identity providers: {result.Data}");
}

LinkIdentityAsync

Task<CloudBaseResponse<LinkIdentityResData>> auth.LinkIdentityAsync(LinkIdentityReq @params)

Binds a new third-party identity provider to the current user.

Parameters

@params
LinkIdentityReq

Response

Task
CloudBaseResponse<LinkIdentityResData>

Example

var result = await auth.LinkIdentityAsync(new LinkIdentityReq
{
Provider = "wechat",
});

if (result.IsSuccess)
{
Console.WriteLine("Identity provider bound");
}

UnlinkIdentityAsync

Task<CloudBaseResponse<object?>> auth.UnlinkIdentityAsync(UnlinkIdentityReq @params)

Unbinds a third-party identity provider from the current user.

Parameters

@params
UnlinkIdentityReq

Response

Task
CloudBaseResponse<object?>

Example

var result = await auth.UnlinkIdentityAsync(new UnlinkIdentityReq
{
Provider = "wechat",
});

if (result.IsSuccess)
{
Console.WriteLine("Identity provider unbound");
}

Password Management

ResetPasswordForEmailAsync

Task<CloudBaseResponse<ResetPasswordForEmailResData>> auth.ResetPasswordForEmailAsync(string emailOrPhone, string? redirectTo = null)

Initiates a password reset flow via email or phone number.

Parameters

emailOrPhone
string

Email or phone number

redirectTo
string?

Redirect address after a successful reset

Response

Task
CloudBaseResponse<ResetPasswordForEmailResData>

Example

var result = await auth.ResetPasswordForEmailAsync(
"user@example.com",
"https://your-app.com/reset"
);

if (result.IsSuccess)
{
Console.WriteLine("Password reset email sent");
}

ResetPasswordForOldAsync

Task<CloudBaseResponse<SignInResData>> auth.ResetPasswordForOldAsync(ResetPasswordForOldReq @params)

Changes the password by replacing the old password with a new one.

Parameters

@params
ResetPasswordForOldReq

Response

Task
CloudBaseResponse<SignInResData>

Example

var result = await auth.ResetPasswordForOldAsync(new ResetPasswordForOldReq
{
OldPassword = "oldPassword123",
NewPassword = "newPassword456",
});

if (result.IsSuccess)
{
Console.WriteLine("Password changed");
}

ReauthenticateAsync

Task<CloudBaseResponse<ReauthenticateResData>> auth.ReauthenticateAsync()

Performs secondary authentication on the current user (re-authentication before sensitive operations).

Parameters

No parameters

Response

Task
CloudBaseResponse<ReauthenticateResData>

Example

var result = await auth.ReauthenticateAsync();

if (result.IsSuccess)
{
Console.WriteLine("Secondary authentication succeeded");
}

Verification Management

GetVerificationAsync

Task<CloudBaseResponse<GetVerificationResData>> auth.GetVerificationAsync(string? email = null, string? phoneNumber = null)

Sends a verification code to the specified email or phone number, and returns a verification ID for subsequent verification.

Parameters

email
string?

Email (choose one of this or phoneNumber)

phoneNumber
string?

Phone number (choose one of this or email)

Response

Task
CloudBaseResponse<GetVerificationResData>

Example

var result = await auth.GetVerificationAsync(email: "user@example.com");

if (result.IsSuccess)
{
Console.WriteLine($"Verification ID: {result.Data?.VerificationId}");
}

VerifyAsync

Task<CloudBaseResponse<VerifyCodeResData>> auth.VerifyAsync(string verificationId, string verificationCode)

Verifies the verification code entered by the user.

Parameters

verificationId
string

Verification ID returned by GetVerificationAsync

verificationCode
string

Verification code entered by the user

Response

Task
CloudBaseResponse<VerifyCodeResData>

Example

var result = await auth.VerifyAsync("verification-id", "123456");

if (result.IsSuccess)
{
Console.WriteLine("Verification code passed");
}

VerifyOtpAsync

Task<CloudBaseResponse<SignInResData>> auth.VerifyOtpAsync(VerifyOtpReq @params)

Verifies the OTP code and completes login / registration. It is typically invoked via the VerifyOtp callback in the data returned by sign-up or sign-in, but you can also call this method directly.

Parameters

@params
VerifyOtpReq

Response

Task
CloudBaseResponse<SignInResData>

Example

var result = await auth.VerifyOtpAsync(new VerifyOtpReq
{
Token = "123456",
VerificationId = "verification-id",
});

if (result.IsSuccess)
{
Console.WriteLine($"Login succeeded: {result.Data?.User?.Id}");
}

VerifyOAuthAsync

Task<CloudBaseResponse<VerifyOAuthResData>> auth.VerifyOAuthAsync(VerifyOAuthReq? @params = null)

Verifies the OAuth login callback to complete the OAuth login flow.

Parameters

@params
VerifyOAuthReq?

OAuth verification parameters, optional (detected from the URL by default)

Response

Task
CloudBaseResponse<VerifyOAuthResData>

Example

var result = await auth.VerifyOAuthAsync();

if (result.IsSuccess)
{
Console.WriteLine($"OAuth login succeeded: {result.Data}");
}

ResendAsync

Task<CloudBaseResponse<ResendResData>> auth.ResendAsync(ResendReq @params)

Resends the verification code.

Parameters

@params
ResendReq

Response

Task
CloudBaseResponse<ResendResData>

Example

var result = await auth.ResendAsync(new ResendReq
{
VerificationId = "verification-id",
});

if (result.IsSuccess)
{
Console.WriteLine("Verification code resent");
}

GetCaptchaTokenAsync

Task<string?> app.Captcha.GetCaptchaTokenAsync(bool forceNew = false, string state = "")

Gets a captcha token. When human verification is required, the SDK collects user input via the CaptchaConfig.OnCaptchaRequired callback.

Parameters

forceNew
bool

Whether to force fetching a new token, defaults to false

state
string

Verification state identifier, defaults to an empty string

Response

Task
string?

Captcha token; null when retrieval fails

Example

// Configure the human verification callback during initialization
var app = await CloudBase.InitAsync(
env: "your-env-id",
captchaConfig: new CaptchaConfig
{
OnCaptchaRequired = async (state) =>
{
// Pop up your captcha UI and return the token after the user completes verification
return await ShowCaptchaUiAsync(state);
}
}
);

var token = await app.Captcha.GetCaptchaTokenAsync();
Console.WriteLine($"Captcha token: {token}");

CreateCaptchaDataAsync

Task<CreateCaptchaDataRes> app.Captcha.CreateCaptchaDataAsync(string state)

Creates captcha data.

Parameters

state
string

Verification state identifier

Response

Task
CreateCaptchaDataRes

Captcha data

Example

var data = await app.Captcha.CreateCaptchaDataAsync("login");
Console.WriteLine($"Captcha data: {data}");

VerifyCaptchaDataAsync

Task<VerifyCaptchaRes> app.Captcha.VerifyCaptchaDataAsync(string token, string key)

Verifies captcha data.

Parameters

token
string

Captcha token

key
string

Verification key

Response

Task
VerifyCaptchaRes

Verification result

Example

var result = await app.Captcha.VerifyCaptchaDataAsync("token", "key");
Console.WriteLine($"Verification result: {result}");

AppendCaptchaTokenToUrlAsync

Task<string> app.Captcha.AppendCaptchaTokenToUrlAsync(
string url,
string state,
bool forceNew = false)

Gets a captcha token and appends it as a query parameter to the specified URL, returning the assembled URL.

Parameters

url
string

Original URL

state
string

Business-side state identifier

forceNew
bool

Whether to force fetching a new token, defaults to false

Response

Task
string

URL with the captcha token appended

Example

var url = await app.Captcha.AppendCaptchaTokenToUrlAsync(
"https://example.com/api",
"login"
);
Console.WriteLine($"URL: {url}");

FindCaptchaTokenAsync

Task<string?> app.Captcha.FindCaptchaTokenAsync()

Finds a valid captcha token in the local cache; returns null if none exists or it has expired.

Parameters

No parameters

Response

Task
string?

Cached captcha token; null when absent

Example

var token = await app.Captcha.FindCaptchaTokenAsync();
Console.WriteLine($"Cached token: {token}");

ClearCaptchaTokenAsync

Task app.Captcha.ClearCaptchaTokenAsync()

Clears the locally cached captcha token.

Parameters

No parameters

Response

Task
void

No return value

Example

await app.Captcha.ClearCaptchaTokenAsync();
Console.WriteLine("Captcha token cleared");

Document-oriented Database

The document-oriented (NoSQL) database is accessed via app.Database() returning the entry CloudBaseDb, using a fluent chaining style aligned with the JS SDK's app.database().

var db = app.Database(); // Default instance / database
var db2 = app.Database("instance", "db"); // Specify instance and database
var _ = db.Command; // Get the operator set

Database

CloudBaseDb app.Database(string? instance = null, string? database = null)

Get the document-oriented database entry.

Parameters

instance
string?

Database instance identifier, default (default)

database
string?

Database name, default (default)

Response

CloudBaseDb
CloudBaseDb

Document-oriented database entry

Example

var db = app.Database();

Collection

CollectionReference db.Collection(string collectionName)

Get a collection reference for chaining.

Parameters

collectionName
string

Collection name

Response

CollectionReference
CollectionReference

Collection reference

Example

var collection = db.Collection("todos");

CreateCollectionAsync

Task<DbCollectionResult> db.CreateCollectionAsync(string collectionName)

Create a collection.

Parameters

collectionName
string

Collection name

Response

Task
DbCollectionResult

Example

var result = await db.CreateCollectionAsync("todos");

if (result.IsSuccess)
{
Console.WriteLine("Collection created successfully");
}

Add

Task<DbAddResult> db.Collection(name).Add(object data)

Add records. Passing a single object adds a single record (returns Id); passing a collection of objects performs a batch add (returns Ids).

Parameters

data
object

A single document object or a collection of document objects

Response

Task
DbAddResult

Example

var result = await db.Collection("todos").Add(new
{
title = "Learn CloudBase",
completed = false,
});

Console.WriteLine($"Added document ID: {result.Id}");

Where

Query query.Where(object condition)

Set query conditions; can be called multiple times to merge conditions. Field values in the condition can be combined with db.Command operators.

Parameters

condition
object

Query condition object (anonymous object / dictionary / fields with operators)

Response

Query
Query

Query builder (supports continued chaining)

Example

var _ = db.Command;

var result = await db.Collection("todos")
.Where(new Dictionary<string, object?>
{
["completed"] = false,
["priority"] = _.Gte(2),
})
.Get();

foreach (var doc in result.Data)
{
Console.WriteLine(doc["title"]);
}

OrderBy

Query query.OrderBy(string fieldPath, string direction = "asc")

Set sorting; can be called multiple times to sort by multiple fields.

Parameters

fieldPath
string

Sort field path

direction
string

Sort direction: asc ascending (default), desc descending

Response

Query
Query

Query builder

Example

var result = await db.Collection("todos")
.OrderBy("createdAt", "desc")
.Get();

Limit

Query query.Limit(int max)

Limit the maximum number of records returned.

Parameters

max
int

Maximum number of records

Response

Query
Query

Query builder

Example

var result = await db.Collection("todos").Limit(10).Get();

Skip

Query query.Skip(int offset)

Set the result offset, used for pagination.

Parameters

offset
int

Offset

Response

Query
Query

Query builder

Example

var result = await db.Collection("todos")
.Skip(20)
.Limit(10)
.Get();

Field

Query query.Field(object projection)

Specify the fields to return (projection).

Parameters

projection
object

Field projection, e.g. new { title = true, content = false }

Response

Query
Query

Query builder

Example

var result = await db.Collection("todos")
.Field(new { title = true, completed = true })
.Get();

Get

Task<DbQueryResult> query.Get()

Execute the query and return the list of matching documents. Query / CollectionReference / DocumentReference all support direct await, equivalent to calling Get().

Parameters

No parameters

Response

Task
DbQueryResult

Example

var result = await db.Collection("todos")
.Where(new { completed = false })
.OrderBy("createdAt", "desc")
.Limit(10)
.Get();

foreach (var doc in result.Data)
{
Console.WriteLine(doc["title"]);
}

Count

Task<DbCountResult> query.Count()

Count the number of documents matching the conditions.

Parameters

No parameters

Response

Task
DbCountResult

Example

var result = await db.Collection("todos")
.Where(new { completed = false })
.Count();

Console.WriteLine($"Incomplete: {result.Total}");

Update

Task<DbUpdateResult> query.Update(object data)

Batch update documents matching the conditions. Regular fields are automatically grouped into $set, while operators (e.g. _.Inc(1)) are grouped by semantics.

Parameters

data
object

Update content

Response

Task
DbUpdateResult

Example

var _ = db.Command;

var result = await db.Collection("todos")
.Where(new { completed = false })
.Update(new Dictionary<string, object?>
{
["completed"] = true,
["views"] = _.Inc(1),
});

Console.WriteLine($"Updated {result.Updated} records");

Remove

Task<DbDeleteResult> query.Remove()

Batch delete documents matching the conditions.

Parameters

No parameters

Response

Task
DbDeleteResult

Example

var result = await db.Collection("todos")
.Where(new { completed = true })
.Remove();

Console.WriteLine($"Deleted {result.Deleted} records");

Doc

DocumentReference db.Collection(name).Doc(string docId)

Get a document reference by document ID, used to perform Get / Set / Update / Remove on a single record.

Parameters

docId
string

Document ID

Response

DocumentReference
DocumentReference

Document reference

Example

var result = await db.Collection("todos").Doc("doc-id-123").Get();

if (result.IsSuccess && result.Data.Count > 0)
{
Console.WriteLine(result.Data[0]["title"]);
}

OfType

TypedQuery<T> db.Collection(name).OfType<T>()

Enter strongly-typed query mode, returning an expression-tree-based TypedQuery<T> that supports compile-time type-safe queries, sorting, and pagination such as Where(x => x.Completed == false).

Parameters

No parameters

Response

TypedQuery<T>
TypedQuery<T>

Strongly-typed query builder

Example

public class Todo
{
public string Title { get; set; } = "";
public bool Completed { get; set; }
public int Priority { get; set; }
public long CreatedAt { get; set; }
}

var res = await db.Collection("todos").OfType<Todo>()
.Where(x => !x.Completed && x.Priority >= 2)
.OrderByDescending(x => x.CreatedAt)
.Limit(10)
.Get();

foreach (var todo in res.Data)
{
Console.WriteLine(todo.Title); // todo is a strongly-typed Todo
}

Aggregate

DbAggregate db.Collection(name).Aggregate()

Get the aggregation object, append aggregation stages in order, and finally execute with End(). Supports stages such as Match / Group / Sort / Project / Limit / Skip / Lookup / Unwind / AddFields / Count / Sample / ReplaceRoot / SortByCount / Bucket / BucketAuto / GeoNear.

Parameters

No parameters

Response

DbAggregate
DbAggregate

Aggregation object

Example

var result = await db.Collection("orders")
.Aggregate()
.Match(new { status = "paid" })
.Group(new Dictionary<string, object?>
{
["_id"] = "$userId",
["total"] = new Dictionary<string, object?> { ["$sum"] = "$amount" },
})
.Sort(new { total = -1 })
.Limit(10)
.End();

foreach (var row in result.Data)
{
Console.WriteLine($"{row["_id"]}: {row["total"]}");
}

StartTransactionAsync

Task<DbTransaction> db.StartTransactionAsync()

Start a transaction, returning a chainable transaction object DbTransaction. Operate on documents within the transaction via transaction.Collection(name), then CommitAsync() to commit or RollbackAsync() to roll back.

Parameters

No parameters

Response

Task
DbTransaction

Example

var transaction = await db.StartTransactionAsync();

if (transaction.IsSuccess)
{
try
{
await transaction.Collection("accounts").Doc("a")
.Update(new Dictionary<string, object?> { ["balance"] = db.Command.Inc(-100) });
await transaction.Collection("accounts").Doc("b")
.Update(new Dictionary<string, object?> { ["balance"] = db.Command.Inc(100) });

await transaction.CommitAsync(); // Commit
}
catch
{
await transaction.RollbackAsync(); // Rollback
}
}

RunCommandsAsync

Task<DbCommandResult> db.RunCommandsAsync(
IEnumerable<object?> commands,
string? transactionId = null)

Execute native MongoDB commands.

Parameters

commands
IEnumerable<object?>

Command array, each element is a native MongoDB command object

transactionId
string?

Transaction ID (execute all commands within a transaction, optional)

Response

Task
DbCommandResult

Example

var result = await db.RunCommandsAsync(new object?[]
{
new Dictionary<string, object?>
{
["find"] = "todos",
["filter"] = new Dictionary<string, object?> { ["completed"] = false },
},
});

if (result.IsSuccess)
{
Console.WriteLine($"Command count: {result.List.Count}");
}

RegExp

Dictionary<string, object?> db.RegExp(string regexp, string? options = null)

Construct a regular expression matching object for fuzzy matching in Where, equivalent to MongoDB { $regex, $options }.

Parameters

regexp
string

Regular expression string

options
string?

Regex options, e.g. "i" for case-insensitive

Response

Dictionary<string, object?>
Dictionary<string, object?>

Regex matching object

Example

var result = await db.Collection("todos")
.Where(new Dictionary<string, object?>
{
["title"] = db.RegExp("cloud", "i"),
})
.Get();

Command

DbCommand db.Command

Database operator set (aligned with db.command), divided into query operators and update operators, returning MongoDB-style operator objects that can be used directly as field values in Where / Update.

Parameters

No parameters

Response

DbCommand
DbCommand

Operator set

Example

var _ = db.Command;

// Comparison: Eq / Neq / Gt / Gte / Lt / Lte / In / Nin
// Logical: And / Or / Not / Nor
// Field/Array: Exists / Mod / All / ElemMatch / Size
var result = await db.Collection("users")
.Where(new Dictionary<string, object?>
{
["age"] = _.Gt(18),
["tags"] = _.In(new[] { "vip", "new" }),
})
.Get();

Data Model

Data models are accessed via app.Models. You can use the indexer app.Models["modelName"] or app.Models.Model("modelName") to obtain an operation handle (CloudBaseModel) bound to the specified model, or you can directly call methods on app.Models that accept a modelName parameter.

var models = app.Models;
var userModel = models["user"]; // Bound handle; methods no longer need the modelName argument

GetByIdAsync

Task<ModelFindResponse> models.GetByIdAsync(string modelName, string recordId)
// Or use the bound handle
Task<ModelFindResponse> model.GetByIdAsync(string recordId)

Retrieves a single record by its record ID.

Parameters

modelName
string

Model (data table) name (not required when using a bound handle)

recordId
string

Record ID

Response

Task
ModelFindResponse

Example

var result = await app.Models.GetByIdAsync("user", "record-id-123");

if (result.IsSuccess)
{
Console.WriteLine($"Record: {result.Data}");
}

GetAsync

Task<ModelFindResponse> models.GetAsync(string modelName, Dictionary<string, object?>? filter = null, Dictionary<string, object?>? select = null)

Retrieves a single record based on filter conditions.

Parameters

modelName
string

Model name

filter
Dictionary<string, object?>?

Filter conditions

select
Dictionary<string, object?>?

Fields to return

Response

Task
ModelFindResponse

Example

var result = await app.Models.GetAsync(
"user",
filter: new Dictionary<string, object?>
{
["where"] = new Dictionary<string, object?>
{
["email"] = new Dictionary<string, object?> { ["$eq"] = "user@example.com" }
}
}
);

if (result.IsSuccess)
{
Console.WriteLine($"Record: {result.Data}");
}

ListAsync

Task<ModelFindManyResponse> models.ListAsync(
string modelName,
Dictionary<string, object?>? filter = null,
Dictionary<string, object?>? select = null,
int? pageSize = null,
int? pageNumber = null,
bool? getCount = null,
List<Dictionary<string, string>>? orderBy = null)

Queries multiple records with pagination.

Parameters

modelName
string

Model name

filter
Dictionary<string, object?>?

Filter conditions

select
Dictionary<string, object?>?

Fields to return

pageSize
int?

Page size

pageNumber
int?

Page number

getCount
bool?

Whether to return the total count

orderBy
List<Dictionary<string, string>>?

Sort rules

Response

Task
ModelFindManyResponse

Example

var result = await app.Models.ListAsync(
"user",
filter: new Dictionary<string, object?>
{
["where"] = new Dictionary<string, object?>
{
["status"] = new Dictionary<string, object?> { ["$eq"] = "active" }
}
},
pageSize: 10,
pageNumber: 1,
getCount: true,
orderBy: new List<Dictionary<string, string>>
{
new() { ["createdAt"] = "desc" }
}
);

if (result.IsSuccess)
{
Console.WriteLine($"Record list: {result.Data}");
}

ListSimpleAsync

Task<ModelFindManyResponse> models.ListSimpleAsync(string modelName, int? pageSize = null, int? pageNumber = null, bool? getCount = null)

A simplified version for querying multiple records with pagination (no filtering or sorting).

Parameters

modelName
string

Model name

pageSize
int?

Page size

pageNumber
int?

Page number

getCount
bool?

Whether to return the total count

Response

Task
ModelFindManyResponse

Example

var result = await app.Models.ListSimpleAsync("user", pageSize: 20, pageNumber: 1, getCount: true);

if (result.IsSuccess)
{
Console.WriteLine($"Record list: {result.Data}");
}

CreateAsync

Task<ModelCreateResponse> models.CreateAsync(string modelName, Dictionary<string, object?> data)

Creates a single record.

Parameters

modelName
string

Model name

data
Dictionary<string, object?>

Record data

Response

Task
ModelCreateResponse

Example

var result = await app.Models.CreateAsync("user", new Dictionary<string, object?>
{
["name"] = "Zhang San",
["email"] = "zhangsan@example.com",
});

if (result.IsSuccess)
{
Console.WriteLine($"Created successfully: {result.Data}");
}

CreateManyAsync

Task<ModelCreateManyResponse> models.CreateManyAsync(string modelName, List<Dictionary<string, object?>> data)

Creates multiple records in bulk.

Parameters

modelName
string

Model name

data
List<Dictionary<string, object?>>

List of record data

Response

Task
ModelCreateManyResponse

Example

var result = await app.Models.CreateManyAsync("user", new List<Dictionary<string, object?>>
{
new() { ["name"] = "Zhang San" },
new() { ["name"] = "Li Si" },
});

if (result.IsSuccess)
{
Console.WriteLine($"Bulk created successfully: {result.Data}");
}

UpdateAsync

Task<ModelUpdateDeleteResponse> models.UpdateAsync(string modelName, Dictionary<string, object?> filter, Dictionary<string, object?> data)

Updates a single record matching the conditions.

Parameters

modelName
string

Model name

filter
Dictionary<string, object?>

Filter conditions

data
Dictionary<string, object?>

Update data

Response

Task
ModelUpdateDeleteResponse

Example

var result = await app.Models.UpdateAsync(
"user",
filter: new Dictionary<string, object?>
{
["where"] = new Dictionary<string, object?>
{
["_id"] = new Dictionary<string, object?> { ["$eq"] = "record-id-123" }
}
},
data: new Dictionary<string, object?> { ["name"] = "Zhang Sansan" }
);

if (result.IsSuccess)
{
Console.WriteLine($"Updated successfully: {result.Data}");
}

UpdateManyAsync

Task<ModelUpdateDeleteManyResponse> models.UpdateManyAsync(string modelName, Dictionary<string, object?> filter, Dictionary<string, object?> data)

Updates multiple records matching the conditions in bulk.

Parameters

modelName
string

Model name

filter
Dictionary<string, object?>

Filter conditions

data
Dictionary<string, object?>

Update data

Response

Task
ModelUpdateDeleteManyResponse

Example

var result = await app.Models.UpdateManyAsync(
"user",
filter: new Dictionary<string, object?>
{
["where"] = new Dictionary<string, object?>
{
["status"] = new Dictionary<string, object?> { ["$eq"] = "inactive" }
}
},
data: new Dictionary<string, object?> { ["status"] = "active" }
);

if (result.IsSuccess)
{
Console.WriteLine($"Bulk updated successfully: {result.Data}");
}

UpsertAsync

Task<ModelUpsertResponse> models.UpsertAsync(
string modelName,
Dictionary<string, object?> filter,
Dictionary<string, object?>? create = null,
Dictionary<string, object?>? update = null)

Updates a record matching the filter conditions, or creates it if it does not exist.

Parameters

modelName
string

Model name

filter
Dictionary<string, object?>

Filter conditions

create
Dictionary<string, object?>?

Data to create when the record does not exist

update
Dictionary<string, object?>?

Data to update when the record exists

Response

Task
ModelUpsertResponse

Example

var result = await app.Models.UpsertAsync(
"user",
filter: new Dictionary<string, object?>
{
["where"] = new Dictionary<string, object?>
{
["email"] = new Dictionary<string, object?> { ["$eq"] = "user@example.com" }
}
},
create: new Dictionary<string, object?> { ["email"] = "user@example.com", ["name"] = "New User" },
update: new Dictionary<string, object?> { ["name"] = "Updated User" }
);

if (result.IsSuccess)
{
Console.WriteLine($"Upsert successful: {result.Data}");
}

DeleteByIdAsync

Task<ModelUpdateDeleteResponse> models.DeleteByIdAsync(string modelName, string recordId)

Deletes a single record by its record ID.

Parameters

modelName
string

Model name

recordId
string

Record ID

Response

Task
ModelUpdateDeleteResponse

Example

var result = await app.Models.DeleteByIdAsync("user", "record-id-123");

if (result.IsSuccess)
{
Console.WriteLine("Deleted successfully");
}

DeleteRecordAsync

Task<ModelUpdateDeleteResponse> models.DeleteRecordAsync(string modelName, Dictionary<string, object?> filter)

Deletes a single record matching the conditions (corresponding to DeleteAsync on the bound handle).

Parameters

modelName
string

Model name

filter
Dictionary<string, object?>

Filter conditions

Response

Task
ModelUpdateDeleteResponse

Example

var result = await app.Models.DeleteRecordAsync(
"user",
filter: new Dictionary<string, object?>
{
["where"] = new Dictionary<string, object?>
{
["email"] = new Dictionary<string, object?> { ["$eq"] = "user@example.com" }
}
}
);

if (result.IsSuccess)
{
Console.WriteLine("Deleted successfully");
}

DeleteManyAsync

Task<ModelUpdateDeleteManyResponse> models.DeleteManyAsync(string modelName, Dictionary<string, object?> filter)

Deletes multiple records matching the conditions in bulk.

Parameters

modelName
string

Model name

filter
Dictionary<string, object?>

Filter conditions

Response

Task
ModelUpdateDeleteManyResponse

Example

var result = await app.Models.DeleteManyAsync(
"user",
filter: new Dictionary<string, object?>
{
["where"] = new Dictionary<string, object?>
{
["status"] = new Dictionary<string, object?> { ["$eq"] = "deleted" }
}
}
);

if (result.IsSuccess)
{
Console.WriteLine($"Bulk deleted successfully: {result.Data}");
}

MysqlCommandAsync

Task<ModelMysqlCommandResponse> models.MysqlCommandAsync(
string sqlTemplate,
List<ModelMysqlParameter>? parameter = null,
ModelMysqlConfig? config = null)

Executes a MySQL command via the Data Model (parameterized SQL template).

Parameters

sqlTemplate
string

Parameterized SQL template

parameter
List<ModelMysqlParameter>?

List of SQL parameters

config
ModelMysqlConfig?

Execution configuration

Response

Task
ModelMysqlCommandResponse

Example

var result = await app.Models.MysqlCommandAsync(
"SELECT * FROM user WHERE age > ?",
parameter: new List<ModelMysqlParameter>
{
new() { Value = 18 }
}
);

if (result.IsSuccess)
{
Console.WriteLine($"Query result: {result.Data}");
}

Data Source Query

GetAggregateDataSourceListAsync

Task<AggregateDataSourceListResponse> models.GetAggregateDataSourceListAsync(
int pageSize,
string? envId = null,
int? pageIndex = null,
int? queryAll = null,
List<string>? dataSourceIds = null,
List<string>? dataSourceNames = null,
string? dataSourceType = null,
List<string>? viewIds = null,
List<string>? appIds = null,
int? appLinkStatus = null,
int? queryBindToApp = null,
int? queryConnector = null,
List<string>? channelList = null,
bool? queryDataSourceRelationList = null,
string? dbInstanceType = null,
List<string>? databaseTableNames = null,
bool? querySystemModel = null)

Query the aggregated data source list by conditions. envId is optional and defaults to the environment ID used during initialization.

Parameters

pageSize
int

Number of items per page

envId
string?

Environment ID (optional, defaults to the env used during initialization)

pageIndex
int?

Page number

queryAll
int?

Whether to query all (0 or 1)

dataSourceIds
List<string>?

List of data source IDs

dataSourceNames
List<string>?

List of data source names

dataSourceType
string?

Data source type

querySystemModel
bool?

Whether to query system models

Response

Task
AggregateDataSourceListResponse

Example

var result = await app.Models.GetAggregateDataSourceListAsync(
pageSize: 10,
pageIndex: 0
);

if (result.IsSuccess)
{
Console.WriteLine($"Total: {result.Count}");
}

GetDataSourceAggregateDetailAsync

Task<DataSourceAggregateDetailResponse> models.GetDataSourceAggregateDetailAsync(
string? datasourceId = null,
string? dataSourceName = null,
string? viewId = null,
int? queryPublish = null,
bool? queryModelRelation = null,
string? dbInstanceType = null,
string? databaseTableName = null)

Query the aggregated details of a data source.

Parameters

datasourceId
string?

Data source ID (either this or dataSourceName)

dataSourceName
string?

Data source name

queryModelRelation
bool?

Whether to query model relations

Response

Task
DataSourceAggregateDetailResponse

Example

var result = await app.Models.GetDataSourceAggregateDetailAsync(
dataSourceName: "user"
);

if (result.IsSuccess)
{
Console.WriteLine($"Details: {result}");
}

GetDataSourceByTableNameAsync

Task<DataSourceByTableNameResponse> models.GetDataSourceByTableNameAsync(List<string> tableNames)

Query the corresponding data sources by a list of database table names.

Parameters

tableNames
List<string>

List of database table names

Response

Task
DataSourceByTableNameResponse

Example

var result = await app.Models.GetDataSourceByTableNameAsync(
new List<string> { "user_table" }
);

if (result.IsSuccess)
{
Console.WriteLine($"Data Source: {result}");
}

GetBasicDataSourceListAsync

Task<BasicDataSourceListResponse> models.GetBasicDataSourceListAsync(
List<string>? idList = null,
List<string>? nameList = null,
int? pageNum = null,
int? pageSize = null,
bool? queryAll = null,
List<DataSourceQueryFilter>? queryFilterList = null,
bool? onlyFlexDb = null)

Query the list of basic data source information by conditions.

Parameters

idList
List<string>?

List of data source IDs

nameList
List<string>?

List of data source names

pageNum
int?

Page number

pageSize
int?

Number of items per page

queryAll
bool?

Whether to query all

queryFilterList
List<DataSourceQueryFilter>?

List of query filters

onlyFlexDb
bool?

Whether to query only flexible databases

Response

Task
BasicDataSourceListResponse

Example

var result = await app.Models.GetBasicDataSourceListAsync(pageNum: 1, pageSize: 10);

if (result.IsSuccess)
{
Console.WriteLine($"List: {result}");
}

GetBasicDataSourceAsync

Task<BasicDataSourceResponse> models.GetBasicDataSourceAsync(
string? datasourceId = null,
string? dataSourceName = null,
string? viewId = null,
int? queryPublish = null,
bool? queryModelRelation = null,
string? dbInstanceType = null,
string? databaseTableName = null)

Query a single basic data source by conditions.

Parameters

datasourceId
string?

Data source ID (either this or dataSourceName)

dataSourceName
string?

Data source name

viewId
string?

View ID

queryModelRelation
bool?

Whether to query model relations

Response

Task
BasicDataSourceResponse

Example

var result = await app.Models.GetBasicDataSourceAsync(dataSourceName: "user");

if (result.IsSuccess)
{
Console.WriteLine($"Data Source: {result}");
}

GetSchemaListAsync

Task<DataSourceSchemaListResponse> models.GetSchemaListAsync(List<string>? dataSourceNameList = null)

Query the schemas of all data sources in the environment, with optional filtering by a list of data source names.

Parameters

dataSourceNameList
List<string>?

List of data source names (optional; if empty, all are queried)

Response

Task
DataSourceSchemaListResponse

Example

var result = await app.Models.GetSchemaListAsync();

if (result.IsSuccess)
{
Console.WriteLine($"Schema list: {result}");
}

GetTableNameAsync

Task<DataSourceTableNameResponse> models.GetTableNameAsync(string? dataSourceName = null)

Query the corresponding database table name by data source name.

Parameters

dataSourceName
string?

Data source name

Response

Task
DataSourceTableNameResponse

Example

var result = await app.Models.GetTableNameAsync("user");

if (result.IsSuccess)
{
Console.WriteLine($"Table name: {result}");
}

MySQL Database

MySQL RESTful database operations are accessed via app.MySql and provide two styles:

  • Flat methods: QueryAsync, InsertAsync, UpdateAsync, DeleteAsync, CountAsync. You pass the table name and options in a single call. Supported filter operators: eq, neq, gt, gte, lt, lte, like, in, is.
  • Chained Query Builder: app.MySql.From(table)...., PostgREST-style, more readable, supports direct await.

QueryAsync

Task<MySqlResponse> mysql.QueryAsync(
string table,
string? schema = null,
string? instance = null,
MySqlQueryOptions? options = null)

Query data from a MySQL table.

Parameters

table
string

Table name

schema
string?

Schema name

instance
string?

Instance identifier

options
MySqlQueryOptions?

Query options (Select/Limit/Offset/Order/Filters/WithCount)

Response

Task
MySqlResponse

Example

var result = await app.MySql.QueryAsync(
"users",
options: new MySqlQueryOptions
{
Select = "id,name,email",
Limit = 10,
Filters = new Dictionary<string, string> { ["age"] = "gte.18" },
WithCount = true
}
);

if (result.IsSuccess)
{
Console.WriteLine($"Data: {result.Data}, Total: {result.Total}");
}

InsertAsync

Task<MySqlWriteResponse> mysql.InsertAsync(
string table,
object data,
string? schema = null,
string? instance = null,
bool upsert = false,
string? onConflict = null)

Insert data into a MySQL table, with optional upsert.

Parameters

table
string

Table name

data
object

Data to insert (a single object or an array)

upsert
bool

Whether to perform an upsert, default false

onConflict
string?

Conflict resolution field (for upsert)

Response

Task
MySqlWriteResponse

Example

var result = await app.MySql.InsertAsync("users", new
{
name = "John",
email = "john@example.com",
age = 25
});

if (result.IsSuccess)
{
Console.WriteLine($"Insert succeeded: {result.Data}");
}

UpdateAsync (MySQL)

Task<MySqlWriteResponse> mysql.UpdateAsync(
string table,
Dictionary<string, object?> data,
Dictionary<string, string> filters,
string? schema = null,
string? instance = null)

Update rows matching the conditions in a MySQL table.

Parameters

table
string

Table name

data
Dictionary<string, object?>

Fields and values to update

filters
Dictionary<string, string>

Filter conditions, value format such as eq.value

Response

Task
MySqlWriteResponse

Example

var result = await app.MySql.UpdateAsync(
"users",
data: new Dictionary<string, object?> { ["name"] = "Jane" },
filters: new Dictionary<string, string> { ["id"] = "eq.1" }
);

if (result.IsSuccess)
{
Console.WriteLine($"Update succeeded: {result.Data}");
}

DeleteAsync (MySQL)

Task<MySqlWriteResponse> mysql.DeleteAsync(
string table,
Dictionary<string, string> filters,
string? schema = null,
string? instance = null)

Delete rows matching the conditions from a MySQL table.

Parameters

table
string

Table name

filters
Dictionary<string, string>

Filter conditions, value format such as eq.value

Response

Task
MySqlWriteResponse

Example

var result = await app.MySql.DeleteAsync(
"users",
filters: new Dictionary<string, string> { ["id"] = "eq.1" }
);

if (result.IsSuccess)
{
Console.WriteLine("Delete succeeded");
}

CountAsync

Task<MySqlCountResponse> mysql.CountAsync(
string table,
Dictionary<string, string>? filters = null,
string? schema = null,
string? instance = null)

Count the number of records matching the conditions in a MySQL table.

Parameters

table
string

Table name

filters
Dictionary<string, string>?

Filter conditions, value format such as eq.value

Response

Task
MySqlCountResponse

Example

var result = await app.MySql.CountAsync(
"users",
filters: new Dictionary<string, string> { ["age"] = "gte.18" }
);

if (result.IsSuccess)
{
Console.WriteLine($"Record count: {result.Count}");
}

Chained Query Builder

In addition to the flat methods above, app.MySql also provides a PostgREST-style chained query builder that reads closer to SQL, offers better readability, and supports direct await (no need to explicitly call ExecuteAsync).

// Entry 1: default instance/database
app.MySql.From("articles")

// Entry 2: specify instance / database
app.MySql.Rdb(instance: "inst-xxx", database: "mydb").From("articles")
  • From(table) / Rdb(instance, database).From(table): select the data table, returns MySqlQueryBuilder.
  • Operations: Select, Insert, Update, Upsert, Delete.
  • Filter operators: Eq, Neq, Gt, Gte, Lt, Lte, Like, Is, In, Match, Not, Or, Filter.
  • Modifiers: Order, Limit, Range, Single, MaybeSingle.
  • Execution: ExecuteAsync(), or directly await the builder (supported internally via GetAwaiter()).
tip

Update and Delete must include at least one filter condition (WHERE); otherwise they directly return a BadApiRequest error to avoid accidental full-table operations.

// Equivalent to SELECT id,title FROM articles WHERE views > 100 ORDER BY views DESC LIMIT 10
var res = await app.MySql
.From("articles")
.Select("id,title,views")
.Gt("views", 100)
.Order("views", ascending: false)
.Limit(10);

if (res.IsSuccess)
{
foreach (var row in res.Data)
{
Console.WriteLine($"{row["id"]}: {row["title"]}");
}
Console.WriteLine($"Total: {res.Total}");
}

Filter operator reference

MethodDescriptionExample
Eq(col, v)Equal to.Eq("id", 1)
Neq(col, v)Not equal to.Neq("status", "draft")
Gt / Gte / Lt / LteGreater than / greater than or equal / less than / less than or equal.Gt("views", 100)
Like(col, pattern)Fuzzy match, % wildcard.Like("title", "%hot%")
Is(col, v)Null check / boolean assertion.Is("title", null)
In(col, values)Included in array.In("id", new[] {1,2,3})
Match(dict)Multi-column equality match.Match(new Dictionary<string, object?> {...})
Not(col, op, v)Negated filter.Not("title", "is", null)
Or(filters)Logical OR (raw syntax).Or("id.eq.2,title.eq.x")
Filter(col, op, v)Generic filter (raw syntax).Filter("views", "gte", 10)

Cloud Function

Cloud Functions are invoked through the top-level app.CallFunctionAsync (recommended). If you need to specify the underlying channel separately, you can also use CallRealFunctionAsync (regular Cloud Function) and CallCloudRunFunctionAsync (function-style CloudBase Run) on app.Functions.

CallFunctionAsync

Task<FunctionResponse> app.CallFunctionAsync(
string name,
FunctionType type = FunctionType.Function,
IDictionary<string, object?>? data = null,
HttpMethod method = HttpMethod.Post,
string path = "/",
IDictionary<string, string>? header = null,
bool parse = true,
CancellationToken cancellationToken = default)

Invokes a Cloud Function or function-style CloudBase Run. Use type to specify the invocation type (FunctionType.Function or FunctionType.CloudRun).

Parameters

name
string

Cloud Function name

type
FunctionType

Invocation type: Function (Cloud Function, default) or CloudRun (function-style CloudBase Run)

data
IDictionary<string, object?>?

Parameters passed to the Cloud Function

method
HttpMethod

HTTP method, default POST

path
string

Request path, default /

header
IDictionary<string, string>?

Custom request headers

parse
bool

Whether to parse the response result, default true

Response

Task
FunctionResponse

Example

var result = await app.CallFunctionAsync(
name: "hello",
data: new Dictionary<string, object?> { ["name"] = "CloudBase" }
);

if (result.IsSuccess)
{
Console.WriteLine($"Return result: {result.Result}");
}
else
{
Console.WriteLine($"Invocation failed: {result.Message}");
}

CallRealFunctionAsync

Task<FunctionResponse> app.Functions.CallRealFunctionAsync(
string name,
IDictionary<string, object?>? data = null,
bool parse = true,
CancellationToken cancellationToken = default)

Directly invokes a regular Cloud Function (underlying channel), equivalent to CallFunctionAsync with type set to Function.

Parameters

name
string

Cloud Function name

data
IDictionary<string, object?>?

Parameters passed to the Cloud Function

parse
bool

Whether to parse the response result, default true

Response

Task
FunctionResponse

Example

var result = await app.Functions.CallRealFunctionAsync(
"hello",
new Dictionary<string, object?> { ["name"] = "CloudBase" }
);

if (result.IsSuccess)
{
Console.WriteLine($"Return result: {result.Result}");
}

CallCloudRunFunctionAsync

Task<FunctionResponse> app.Functions.CallCloudRunFunctionAsync(
string name,
HttpMethod method = HttpMethod.Post,
string path = "/",
IDictionary<string, string>? header = null,
IDictionary<string, object?>? data = null,
CancellationToken cancellationToken = default)

Invokes a function-style CloudBase Run (underlying channel), equivalent to CallFunctionAsync with type set to CloudRun.

Parameters

name
string

Function-style CloudBase Run service name

method
HttpMethod

HTTP method, default POST

path
string

Request path, default /

header
IDictionary<string, string>?

Custom request headers

data
IDictionary<string, object?>?

Request data

Response

Task
FunctionResponse

Example

var result = await app.Functions.CallCloudRunFunctionAsync(
"my-cloudrun-func",
data: new Dictionary<string, object?> { ["key"] = "value" }
);

if (result.IsSuccess)
{
Console.WriteLine($"Return result: {result.Result}");
}

CloudBase Run

CallContainerAsync

Task<CloudRunResponse> app.CallContainerAsync(
string name,
HttpMethod method = HttpMethod.Get,
string path = "/",
IDictionary<string, string>? header = null,
IDictionary<string, object?>? data = null,
CancellationToken cancellationToken = default)

Invokes a CloudBase Run container service.

Parameters

name
string

CloudBase Run service name

method
HttpMethod

HTTP method, default GET

path
string

Request path, default /

header
IDictionary<string, string>?

Custom request headers

data
IDictionary<string, object?>?

Request data

Response

Task
CloudRunResponse

Example

var result = await app.CallContainerAsync(
name: "my-service",
method: HttpMethod.Post,
path: "/api/data",
data: new Dictionary<string, object?> { ["key"] = "value" }
);

Console.WriteLine($"Return result: {result.Result}");

APIs

APIs are accessed via app.Apis. Use the indexer app.Apis["apiName"] or app.Apis.Api("apiName") to obtain a method proxy (ApiMethodProxy), then call GetAsync, PostAsync, PutAsync, DeleteAsync, HeadAsync, OptionsAsync, PatchAsync by HTTP method, or use the generic RequestAsync(method, ...). You can also directly call app.Apis.CallApiAsync(CallApiOptions). app.Apis.GatewayOrigin can be used to read/set the gateway origin.

Apis[name]

ApiMethodProxy app.Apis[string apiName]

Gets the method proxy ApiMethodProxy for the specified API. app.Apis.Api("apiName") is equivalent to the indexer app.Apis["apiName"].

ApiMethodProxy provides the following methods, all returning Task<ApiResponse>:

MethodHTTPSignature (excluding cancellationToken)
GetAsyncGET(string path = "", Dictionary<string,string>? headers = null, string? token = null)
PostAsyncPOST(Dictionary<string,object?>? body = null, string path = "", Dictionary<string,string>? headers = null, string? token = null)
PutAsyncPUTSame as PostAsync
PatchAsyncPATCHSame as PostAsync
DeleteAsyncDELETESame as PostAsync
HeadAsyncHEADSame as GetAsync
OptionsAsyncOPTIONSSame as GetAsync
RequestAsyncAny(string method, Dictionary<string,object?>? body = null, string path = "", ...)

Parameters

apiName
string

API name

Response

Return
ApiMethodProxy

API method proxy, provides methods such as GetAsync/PostAsync/PutAsync/PatchAsync/DeleteAsync/HeadAsync/OptionsAsync/RequestAsync

Example

var result = await app.Apis["myApi"].GetAsync(path: "/users");

if (result.IsSuccess)
{
Console.WriteLine($"Data: {result.Data}");
}

Api(name)

ApiMethodProxy app.Apis.Api(string apiName)

Gets the API method proxy via a method call, fully equivalent to the indexer app.Apis[apiName].

var result = await app.Apis.Api("myApi").GetAsync(path: "/users");

GatewayOrigin

string? app.Apis.GatewayOrigin { get; set; }

Custom gateway address (optional), used to override the default API gateway address.

app.Apis.GatewayOrigin = "https://your-gateway.example.com";
var result = await app.Apis["myApi"].GetAsync(path: "/users");

CallApiAsync

Task<ApiResponse> app.Apis.CallApiAsync(
CallApiOptions options,
CancellationToken cancellationToken = default)

Directly invokes an API via an options object; each HTTP method of ApiMethodProxy is a wrapper around this method.

Parameters

options
CallApiOptions

Call options (Name/Method/Path/Body/Headers/Token, etc.)

Response

Task
ApiResponse

Example

var result = await app.Apis.CallApiAsync(new CallApiOptions("myApi")
{
Method = "POST",
Path = "/users",
Body = new Dictionary<string, object?> { ["name"] = "Zhang San" }
});

if (result.IsSuccess)
{
Console.WriteLine($"Data: {result.Data}");
}

Cloud Storage

Cloud Storage is accessed via app.Storage. Use app.Storage.From() to obtain a file operation handle (CloudBaseStorageFileApi), then perform upload, download, delete, copy, move and other operations. All methods return StorageResponse<T> (containing Data, Error, IsSuccess).

var storage = app.Storage.From();

Error Handling Pattern (ThrowOnError): By default, each operation reports errors via the Error field of the return value on failure. If ThrowOnError() is called, a StorageException is thrown on failure instead (better suited to exception-style error handling). This method returns the current instance to support chaining:

// Throws StorageException on failure instead of returning Error
var storage = app.Storage.From().ThrowOnError();

try
{
var res = await storage.UploadAsync("a.png", bytes);
}
catch (StorageException ex)
{
Console.WriteLine($"Upload failed: {ex.Message}");
}

UploadAsync

Task<StorageResponse<StorageUploadResult>> storage.UploadAsync(
string path,
byte[] fileData,
StorageUploadOptions? options = null)

Uploads a file to Cloud Storage. Internally it obtains upload information and uploads directly to COS, returning the file ID and path.

Parameters

path
string

File path in Cloud Storage

fileData
byte[]

Binary data of the file

options
StorageUploadOptions?

Upload options (CacheControl/ContentType/Metadata/Upsert)

Response

Task
StorageResponse<StorageUploadResult>

Example

var fileData = await File.ReadAllBytesAsync("local/photo.png");

var result = await app.Storage.From().UploadAsync(
"images/photo.png",
fileData,
new StorageUploadOptions
{
ContentType = "image/png",
Upsert = true
}
);

if (result.IsSuccess)
{
Console.WriteLine($"Upload succeeded: {result.Data?.Id}");
}
else
{
Console.WriteLine($"Upload failed: {result.Error?.Message}");
}

UpdateAsync (Storage)

Task<StorageResponse<StorageUploadResult>> storage.UpdateAsync(
string path,
byte[] fileData,
StorageUploadOptions? options = null)

Overwrites (updates) a file, equivalent to UploadAsync with Upsert = true forced.

Parameters

path
string

File path in Cloud Storage

fileData
byte[]

Binary data of the file

options
StorageUploadOptions?

Upload options (Upsert is forced to true internally)

Response

Task
StorageResponse<StorageUploadResult>

Example

var fileData = await File.ReadAllBytesAsync("local/photo.png");

var result = await app.Storage.From().UpdateAsync("images/photo.png", fileData);

if (result.IsSuccess)
{
Console.WriteLine($"Update succeeded: {result.Data?.Id}");
}

GetUploadInfoAsync

Task<StorageResponse<List<StorageUploadInfo>>> storage.GetUploadInfoAsync(List<string> paths)

Gets the upload information for the specified paths (used for custom direct-upload flows).

Parameters

paths
List<string>

List of file paths

Response

Task
StorageResponse<List<StorageUploadInfo>>

Example

var result = await app.Storage.From().GetUploadInfoAsync(
new List<string> { "images/a.png", "images/b.png" }
);

if (result.IsSuccess)
{
Console.WriteLine($"Upload info: {result.Data}");
}

GetDownloadUrlsAsync

Task<StorageResponse<List<StorageDownloadInfo>>> storage.GetDownloadUrlsAsync(
List<string> fileIds,
int? expiresIn = null)

Batch retrieves download URLs for files.

Parameters

fileIds
List<string>

List of file IDs

expiresIn
int?

Link validity period in seconds

Response

Task
StorageResponse<List<StorageDownloadInfo>>

Example

var result = await app.Storage.From().GetDownloadUrlsAsync(
new List<string> { "cloud://env.xxx/images/photo.png" },
expiresIn: 3600
);

if (result.IsSuccess)
{
Console.WriteLine($"Download URLs: {result.Data}");
}

CreateSignedUrlAsync

Task<StorageResponse<string>> storage.CreateSignedUrlAsync(
string fileId,
int expiresIn,
StorageSignedUrlOptions? options = null)

Creates a signed temporary access URL for a single file.

Parameters

fileId
string

File ID

expiresIn
int

Validity period in seconds

options
StorageSignedUrlOptions?

Signed URL options (e.g. image transformation)

Response

Task
StorageResponse<string>

Example

var result = await app.Storage.From().CreateSignedUrlAsync(
"cloud://env.xxx/images/photo.png",
expiresIn: 3600
);

if (result.IsSuccess)
{
Console.WriteLine($"Signed URL: {result.Data}");
}

CreateSignedUrlsAsync

Task<StorageResponse<List<StorageDownloadInfo>>> storage.CreateSignedUrlsAsync(
List<string> fileIds,
int expiresIn)

Batch creates signed temporary access URLs.

Parameters

fileIds
List<string>

List of file IDs

expiresIn
int

Validity period in seconds

Response

Task
StorageResponse<List<StorageDownloadInfo>>

Example

var result = await app.Storage.From().CreateSignedUrlsAsync(
new List<string> { "cloud://env.xxx/a.png", "cloud://env.xxx/b.png" },
expiresIn: 3600
);

if (result.IsSuccess)
{
Console.WriteLine($"Signed URL list: {result.Data}");
}

CreateSignedUploadUrlAsync

Task<StorageResponse<StorageUploadInfo>> storage.CreateSignedUploadUrlAsync(string path)

Creates signed upload information for the specified path (used for custom direct-upload flows).

Parameters

path
string

File path in Cloud Storage

Response

Task
StorageResponse<StorageUploadInfo>

Example

var result = await app.Storage.From().CreateSignedUploadUrlAsync("images/photo.png");

if (result.IsSuccess)
{
Console.WriteLine($"Upload info: {result.Data}");
}

GetPublicUrlAsync

Task<StorageResponse<string>> storage.GetPublicUrlAsync(
string pathOrFileId,
StorageTransformOptions? options = null)

Gets the public access URL of a file, with optional image transformation parameters.

Parameters

pathOrFileId
string

File path or file ID

options
StorageTransformOptions?

Image transformation options (optional)

Response

Task
StorageResponse<string>

Example

var result = await app.Storage.From().GetPublicUrlAsync("images/photo.png");

if (result.IsSuccess)
{
Console.WriteLine($"Public URL: {result.Data}");
}

DownloadAsync

Task<StorageResponse<byte[]>> storage.DownloadAsync(
string fileId,
StorageTransformOptions? options = null)

Downloads file content and returns the binary data.

Parameters

fileId
string

File ID

options
StorageTransformOptions?

Image transformation options (optional)

Response

Task
StorageResponse<byte[]>

Example

var result = await app.Storage.From().DownloadAsync("cloud://env.xxx/images/photo.png");

if (result.IsSuccess)
{
await File.WriteAllBytesAsync("local/photo.png", result.Data!);
}

InfoAsync

Task<StorageResponse<StorageFileInfo>> storage.InfoAsync(string pathOrFileId)

Gets the metadata of a file (size, type, etc.).

Parameters

pathOrFileId
string

File path or file ID

Response

Task
StorageResponse<StorageFileInfo>

Example

var result = await app.Storage.From().InfoAsync("images/photo.png");

if (result.IsSuccess)
{
Console.WriteLine($"File info: {result.Data}");
}

ExistsAsync

Task<StorageResponse<bool>> storage.ExistsAsync(string pathOrFileId)

Checks whether a file exists.

Parameters

pathOrFileId
string

File path or file ID

Response

Task
StorageResponse<bool>

Example

var result = await app.Storage.From().ExistsAsync("images/photo.png");

if (result.IsSuccess)
{
Console.WriteLine($"Exists: {result.Data}");
}

RemoveAsync

Task<StorageResponse<List<StorageDeleteResult>>> storage.RemoveAsync(List<string> fileIds)

Batch deletes files.

Parameters

fileIds
List<string>

List of file IDs to delete

Response

Task
StorageResponse<List<StorageDeleteResult>>

Example

var result = await app.Storage.From().RemoveAsync(
new List<string> { "cloud://env.xxx/images/photo.png" }
);

if (result.IsSuccess)
{
Console.WriteLine("Deletion succeeded");
}

CopyAsync

Task<StorageResponse<StorageCopyResult>> storage.CopyAsync(
string fromPath,
string toPath,
bool overwrite = true)

Copies a single file.

Parameters

fromPath
string

Source file path

toPath
string

Target file path

overwrite
bool

Whether to overwrite; defaults to true

Response

Task
StorageResponse<StorageCopyResult>

Example

var result = await app.Storage.From().CopyAsync(
"images/photo.png",
"backup/photo.png"
);

if (result.IsSuccess)
{
Console.WriteLine("Copy succeeded");
}

CopyBatchAsync

Task<StorageResponse<List<StorageCopyResult>>> storage.CopyBatchAsync(
List<Dictionary<string, object?>> items)

Batch copies files.

Parameters

items
List<Dictionary<string, object?>>

List of copy items, each containing a source path and a target path

Response

Task
StorageResponse<List<StorageCopyResult>>

Example

var result = await app.Storage.From().CopyBatchAsync(new List<Dictionary<string, object?>>
{
new() { ["from"] = "images/a.png", ["to"] = "backup/a.png" },
new() { ["from"] = "images/b.png", ["to"] = "backup/b.png" },
});

if (result.IsSuccess)
{
Console.WriteLine("Batch copy succeeded");
}

MoveAsync

Task<StorageResponse<StorageCopyResult>> storage.MoveAsync(
string fromPath,
string toPath,
bool overwrite = true)

Moves (renames) a file.

Parameters

fromPath
string

Source file path

toPath
string

Target file path

overwrite
bool

Whether to overwrite; defaults to true

Response

Task
StorageResponse<StorageCopyResult>

Example

var result = await app.Storage.From().MoveAsync(
"images/photo.png",
"images/renamed.png"
);

if (result.IsSuccess)
{
Console.WriteLine("Move succeeded");
}

Changelog

The SDK version number follows Semantic Versioning. For the full change log, see the repository CHANGELOG.md.

1.0.0 - 2026-07-23

The first official release, covering the core capabilities of CloudBase and staying consistent with the HTTP API.

  • Multi-target frameworks: Supports targets such as net10.0 (including dependency injection integration), applicable to .NET Core, console, server-side, and Unity scenarios.
  • Authentication: Anonymous / password / username-verification-code / OTP login, registration and logout, session and user management, identity source binding, password reset, etc.
  • CAPTCHA: CAPTCHA creation, verification, and management.
  • Document Database: Collection and document CRUD, chained queries, aggregation pipelines, transactions, strongly-typed operations.
  • Data Model: Data model CRUD and data source aggregation queries.
  • MySQL Database: Flat methods and a PostgREST-style chained query builder.
  • Cloud Functions / CloudBase Run / APIs: Invoke Cloud Functions, CloudBase Run containers, and APIs gateway interfaces.
  • Cloud Storage: File upload, download, deletion, copy, and move, with support for exception-style error handling (ThrowOnError).
  • Dependency Injection: Provides the AddCloudBase extension method, suitable for scenarios such as ASP.NET Core.