Extensions
EasyAdminBlazor decouples core functionality from extensions: install only the NuGet packages you need to avoid bloating the project. This guide summarizes installation, registration, and basic usage of each extension.
Extension Overview
| Package | Registration | Feature |
|---|---|---|
EasyAdminBlazor.Mail |
AddEasyAdminBlazorMail() |
SMTP / SendCloud email |
EasyAdminBlazor.AliyunSms |
AddEasyAdminBlazorAliyunSms() |
Aliyun SMS |
EasyAdminBlazor.Redis |
AddEasyAdminBlazorRedis(connectionString) |
Redis cache, online status, pub/sub, distributed locks |
EasyAdminBlazor.FusionCache |
AddEasyAdminBlazorFusionCache() |
Hybrid cache acceleration |
EasyAdminBlazor.Captcha |
AddEasyAdminBlazorCaptcha(options) |
Form/login captcha |
EasyAdminBlazor.HtmlEditor |
AddEasyAdminBlazorTinyMCEEditor() |
TinyMCE rich text editor |
EasyAdminBlazor.Chat |
AddEasyAdminBlazorChat() + app.UseChat() |
Real-time chat (requires Redis) |
EasyAdminBlazor.MultiTenant |
AddEasyAdminBlazorMultiTenant() |
Multi-tenant, see Multi-Tenant |
EasyAdminBlazor.Scheduler |
AddEasyAdminBlazorScheduler() |
Scheduled tasks, see Scheduled Tasks |
EasyAdminBlazor.WeChat |
AddEasyAdminBlazorWeChat() |
WeChat Mini Program & WeChat Pay V3 |
Register them all in Program.cs:
builder.AddEasyAdminBlazor(new EasyAdminBlazorOptions { ... })
.AddEasyAdminBlazorMail()
.AddEasyAdminBlazorRedis(configuration["Redis:ConnectionString"]!)
.AddEasyAdminBlazorChat()
.AddEasyAdminBlazorScheduler()
.AddEasyAdminBlazorCaptcha(options => { options.Chars = "0123456789"; });
Redis (EasyAdminBlazor.Redis)
.AddEasyAdminBlazorRedis(configuration["Redis:ConnectionString"]!)
Configuration:
{
"Redis": {
"ConnectionString": "127.0.0.1:6379,poolsize=10"
}
}
Inject IRedisService after registration:
- General cache:
Get<T>/Set<T>/IncrBy/Expire, plus String, Hash, List, Set, and Sorted Set operations - Online status:
JoinOnline/RemoveOnline/GetClientListByOnline/HasOnline - Pub/Sub:
Publish/Subscribe(channels from theSubscribeChannelenum) - Distributed locks:
Lock(key, expireSeconds)/ReleaseLock(lockHandle)
@inject IRedisService Redis
// Cache
Redis.Set("user:1", new UserDto { ... }, TimeSpan.FromMinutes(10));
var user = Redis.Get<UserDto>("user:1");
// Pub/Sub
Redis.Subscribe<MyMessage>(SubscribeChannel.MessageNotification, msg =>
{
// handle the message
});
Redis.Publish(SubscribeChannel.MessageNotification, new MyMessage { ... });
// Distributed lock
var lockHandle = Redis.Lock("order:100", 30);
try
{
// critical section
}
finally
{
Redis.ReleaseLock(lockHandle);
}
The extension also provides an IDistributedCache implementation compatible with the standard distributed cache interface.
Mail (EasyAdminBlazor.Mail)
.AddEasyAdminBlazorMail()
Configure either SMTP:
{
"SmtpSettings": {
"Server": "smtp.example.com",
"Port": 587,
"Username": "your_email@example.com",
"Password": "your_email_password",
"FromEmail": "your_email@example.com",
"EnableSsl": true
}
}
or SendCloud (takes priority when configured):
{
"SendCloud": {
"ApiUser": "your_sendcloud_api_user",
"ApiKey": "your_sendcloud_api_key",
"SenderEmail": "noreply@example.com",
"SenderName": "Your App"
}
}
Inject IEmailService:
@inject IEmailService EmailService
// Plain email; separate multiple recipients with semicolons; isHtml controls the body format
var ok = await EmailService.SendEmailAsync("a@example.com;b@example.com", "Subject", "<h1>Body</h1>", isHtml: true);
// Template email (SendCloud templates)
var (success, message) = await EmailService.SendTemplateEmailAsync(
"a@example.com",
"Notification",
"your_template_name",
new Dictionary<string, object> { ["code"] = "1234" });
SMS (EasyAdminBlazor.AliyunSms)
.AddEasyAdminBlazorAliyunSms()
Configuration:
{
"AliyunSms": {
"AccessKeyId": "your_access_key_id",
"AccessKeySecret": "your_access_key_secret",
"SignName": "your_sign_name"
}
}
Inject ISmsService:
@inject ISmsService SmsService
var ok = await SmsService.SendSmsAsync("13800000000", "SMS_123456", "{\"code\":\"1234\"}");
Captcha (EasyAdminBlazor.Captcha)
.AddEasyAdminBlazorCaptcha(options =>
{
options.Chars = "0123456789";
})
The login captcha is controlled by EasyAdminBlazorOptions.EnableLoginCaptcha. The character set, length, etc. are configured through CaptchaOptions.
Rich Text Editor (EasyAdminBlazor.HtmlEditor)
.AddEasyAdminBlazorTinyMCEEditor()
Configure the script URL (a self-hosted CDN or a local copy works):
{
"TinyMCE": {
"ScriptSrc": "https://cdn.wang-zhan.cn/tinymce_8.3.2/tinymce.min.js"
}
}
Use the AdminEditor component in pages (see the component docs).
Real-Time Chat (EasyAdminBlazor.Chat)
.AddEasyAdminBlazorChat()
// ...
app.UseChat();
Depends on Redis: register the Redis extension before AddEasyAdminBlazorChat(); chat stays disabled when Redis is not configured. See Online Chat for UI usage.
Multi-Tenant (EasyAdminBlazor.MultiTenant)
.AddEasyAdminBlazorMultiTenant()
Separate databases per tenant, domain-based tenant resolution, menu and file isolation. See Multi-Tenant for full details.
Scheduled Tasks (EasyAdminBlazor.Scheduler)
.AddEasyAdminBlazorScheduler()
Supports the [Scheduler] attribute and dynamic management via ISchedulerService, with a management page at /Admin/TaskScheduler. See Scheduled Tasks for full details.
Hybrid Cache (EasyAdminBlazor.FusionCache)
.AddEasyAdminBlazorFusionCache()
Implements ICacheService with FusionCache for hybrid in-memory/Redis caching.
WeChat (EasyAdminBlazor.WeChat)
.AddEasyAdminBlazorWeChat()
Configuration:
{
"Wechat": {
"App": {
"AppKey": "your_app_key",
"AppSecret": "your_app_secret"
},
"PayV3": {
"AppId": "",
"MchId": "",
"ApiV3Key": "",
"CertificatePath": "certs/apiclient_cert.pem",
"KeyPath": "certs/apiclient_key.pem",
"PubPath": "certs/pub_key.pem",
"NotifyUrl": "",
"BaseUrl": "https://api.mch.weixin.qq.com"
}
}
}
Main services:
WeChatAppService: Mini Program login (code → openid/session_key), signature validation/decryption of user data, Mini Program QR code generationWeChatPayV3Service: Native / JSAPI payment, callback verification & decryption, order query/close
@inject WeChatPayV3Service WeChatPay
// Create a Native (PC scan-to-pay) order
var result = await WeChatPay.CreateNativePaymentAsync("Product description", 0.01m, outTradeNo);
if (result.Success)
{
// result.CodeUrl is used to generate the QR code
}
Notes
- Keep extension packages at the same version as the core package
- Do not install extensions you do not use — it avoids bloat and potential conflicts
- Do not commit WeChat Pay certificate files (
certs/) to the repository