開始使用 Supabase .NET SDK

Back
Category : News

Supabase .NET SDK 是您 Supabase 專案的 C# 用戶端。
它透過單一 API 提供 Auth、Database、Storage、Realtime 和 Edge Functions,並處理與 Supabase 平台的通訊。

版本 8.0.0 已發佈,同時也推出了新的 Supabase.Extensions.DependencyInjection 套件。
本文將說明如何設定用戶端,並逐步介紹基本操作。

如果您是從先前的主要版本升級,有些部分已有所變動。
您不需要了解所有細節就能跟隨本教學,但值得知道以下事項:

  • 序列化已從 Newtonsoft.Json 移至 System.Text.Json。自訂轉換器與 [JsonProperty] 屬性需改用 System.Text.Json 的對應功能。
  • 每個服務用戶端現在都接受可注入的 HttpClient,並支援選擇性啟用重試與退避機制。
  • 新增了適用於 ASP.NET Core 的相依性注入套件,下方會詳細說明。
  • 套件目標為 .NET Standard 2.1。這表示不再支援 .NET Framework(其最高支援 .NET Standard 2.0),因此您需要 .NET Core 3.0+ 或 .NET 5+。

如果您想查看完整的變更清單,請查閱 發行說明。
遷移指南 列出了您可能遇到的所有重大變更以及處理方式。

將 meta-package 新增至您的專案。
它會引入所有五個服務套件(Auth、Postgrest、Storage、Realtime 和 Functions):


_10

dotnet add package Supabase


如果您只需要其中一個服務,請直接參考該套件,例如 Supabase.Gotrue 用於 Auth,或 Supabase.Postgrest 用於資料庫。

SDK 會將資料表對應至 C# 類別。
模型繼承自 BaseModel,並使用屬性將其屬性與欄位連結。

以下是我們將在後續範例中使用的 todos 資料表,包含 id、task 和 is_complete:


_15

using Supabase.Postgrest.Attributes;

_15

using Supabase.Postgrest.Models;

_15

_15

[Table("todos")]

_15

public class Todo : BaseModel

_15

{

_15

[PrimaryKey("id")]

_15

public int Id { get; set; }

_15

_15

[Column("task")]

_15

public string Task { get; set; }

_15

_15

[Column("is_complete")]

_15

public bool IsComplete { get; set; }

_15

}


ASP.NET Core#

安裝相依性注入套件:


_10

dotnet add package Supabase.Extensions.DependencyInjection


在 Program.cs 中註冊用戶端:


_14

using Supabase.Core.Http;

_14

using Supabase.Extensions.DependencyInjection;

_14

_14

var builder = WebApplication.CreateBuilder(args);

_14

builder.Services.AddSupabase(

_14

supabaseUrl: builder.Configuration["Supabase:Url"]!,

_14

supabaseKey: builder.Configuration["Supabase:Key"]!,

_14

configureOptions: options =>

_14

{

_14

options.AutoConnectRealtime = true;

_14

options.PostgrestRetry = new RetryOptions { MaxRetries = 3 };

_14

});

_14

_14

var app = builder.Build();


AddSupabase 會將 Supabase.Client 註冊為 scoped 服務,因此您可以在需要的地方注入它:minimal API endpoint、controller 或您自己的服務。


_13

using Supabase;

_13

_13

public class TodoService(Client supabase)

_13

{

_13

public async Task<List<Todo>> GetOpen()

_13

{

_13

var result = await supabase

_13

.From<Todo>()

_13

.Where(t => t.IsComplete == false)

_13

.Get();

_13

return result.Models;

_13

}

_13

}


它也會分別註冊每個子用戶端(IPostgrestClient、IGotrueClient<User, Session>、IStorageClient<Bucket, FileObject>、IFunctionsClient、IRealtimeClient<RealtimeSocket, RealtimeChannel>),因此只需碰觸單一服務的類別就能只依賴該服務。

我們建置這個擴充套件,讓您能輕鬆設定用戶端,而無需自己手動連接。
Supabase.Client 在建構時會自行建立 HttpClient。如果您以 scoped 或 transient 方式註冊,每次解析都會建立新的 HttpClient(以及新的 socket),在負載下會耗盡連線池。
AddSupabase 透過 IHttpClientFactory 來連接用戶端,讓處理程式能被共用與重用。
為了保持一致性,它會取代您透過 configureOptions 傳入的任何 HttpClient;您的 proxy、重試、Realtime 與其他選項仍然有效。

其他應用程式#

在 ASP.NET Core 之外的 Console 應用程式、Desktop、Mobile 或 Unity 中,請自行建構用戶端並只初始化一次:


_13

using Supabase;

_13

_13

var url = Environment.GetEnvironmentVariable("SUPABASE_URL")!;

_13

var key = Environment.GetEnvironmentVariable("SUPABASE_KEY")!;

_13

_13

var options = new SupabaseOptions

_13

{

_13

AutoRefreshToken = true,

_13

AutoConnectRealtime = true,

_13

};

_13

_13

var supabase = new Client(url, key, options);

_13

await supabase.InitializeAsync();


InitializeAsync 會還原已儲存的工作階段,並在開啟 AutoConnectRealtime 時建立 Realtime 連線。
預設的工作階段處理程式不會儲存任何資料,因此若要在重新啟動後還原登入,請將 SupabaseOptions.SessionHandler 設定為您自己實作的版本,用來儲存與載入工作階段。
請只建立一次用戶端並在應用程式中重複使用。
每次操作都建立新用戶端意味著每次都會建立新的 HttpClient,這與 DI 套件在伺服器上解決的問題相同。

以下範例會使用 supabase 變數,它是一個 Supabase.Client 實例。

查詢資料列#

From<T>() 會針對 T 所對應的資料表開啟查詢。
您可以使用 Where 進行篩選,然後呼叫 Get 來執行查詢。

Get 會回傳 ModeledResponse<T>,您可以在 Models 中找到資料列:


_10

ModeledResponse<Todo> result = await supabase

_10

.From<Todo>()

_10

.Where(t => t.IsComplete == false)

_10

.Get();

_10

List<Todo> todos = result.Models;


插入#

Insert 可以寫入單一模型或清單:


_10

await supabase.From<Todo>().Insert(new Todo { Task = "Write the launch notes", IsComplete = false });


更新與刪除#

更新實體有兩種方式,兩者都有效。
這取決於您是否已取得該資料列。

如果您已經取得模型,請修改其屬性並呼叫 Update。
從 Get 回傳的資料列會帶有自己的識別資訊,因此它知道要寫入哪一筆記錄:


_10

var result = await supabase.From<Todo>().Where(t => t.Id == 1).Get();

_10

var todo = result.Models.First();

_10

_10

todo.IsComplete = true;

_10

await todo.Update<Todo>();

_10

_10

await todo.Delete<Todo>();


如果您沒有模型,可以使用查詢建置器,這能省去一次 Get 查詢。
設定新的值、篩選資料列,然後執行:


_10

await supabase

_10

.From<Todo>()

_10

.Set(t => t.IsComplete, true)

_10

.Where(t => t.IsComplete == false)

_10

.Update();

_10

_10

await supabase

_10

.From<Todo>()

_10

.Where(t => t.IsComplete == true)

_10

.Delete();


雖然這看起來與 Entity Framework 的建置方式非常相似,但行為並不相同。
這裡沒有 DbContext、沒有變更追蹤器,也沒有 SaveChanges。
修改模型的屬性不會有任何作用,直到您呼叫 Update,而且每次呼叫都是獨立的 HTTP 請求。

驗證使用者#

驗證功能位於 supabase.Auth。
使用電子郵件與密碼註冊並登入使用者:


_10

await supabase.Auth.SignUp("[email protected]", "a-secure-password");

_10

_10

var session = await supabase.Auth.SignIn("[email protected]", "a-secure-password");


當 AutoRefreshToken 啟用時,用戶端會在存取權杖到期前自動重新整理,並將其附加至您的資料庫與 Storage 呼叫,因此 Row-Level-Security 會套用至已登入的使用者。
相同的 supabase.Auth 介面也涵蓋 OAuth、magic links、電話與 SSO。

上傳檔案#


_10

await supabase.Storage

_10

.From("avatars")

_10

.Upload("./local/photo.png", "maria/photo.png");


版本 8.0.0 新增了可發佈的金鑰與秘密 API 金鑰,與現有的 anon 和 service 金鑰並存。

在任何會發佈給使用者的應用程式中使用可發佈金鑰或 anon 金鑰。
請將 secret 和 service 金鑰保留在伺服器上。
Service 金鑰會繞過 Row Level Security,因此不應放在用戶端應用程式中。
當您需要此等級的存取權時,請為其使用獨立的用戶端。

您現在已設定好用戶端,可以從 .NET 執行查詢、驗證與 Storage 操作。接下來您可以:

https://supabase.com/blog/getting-started-with-the-supabase-dotnet-sdk

https://www.worldprogramming.org/posts/getting-started-with-the-supabase-net-sdk-gquayn