![]() |
VOOZH | about |
dotnet add package Empezar.BlazorWebAPI --version 2.2.21
NuGet\Install-Package Empezar.BlazorWebAPI -Version 2.2.21
<PackageReference Include="Empezar.BlazorWebAPI" Version="2.2.21" />
<PackageVersion Include="Empezar.BlazorWebAPI" Version="2.2.21" />Directory.Packages.props
<PackageReference Include="Empezar.BlazorWebAPI" />Project file
paket add Empezar.BlazorWebAPI --version 2.2.21
#r "nuget: Empezar.BlazorWebAPI, 2.2.21"
#:package Empezar.BlazorWebAPI@2.2.21
#addin nuget:?package=Empezar.BlazorWebAPI&version=2.2.21Install as a Cake Addin
#tool nuget:?package=Empezar.BlazorWebAPI&version=2.2.21Install as a Cake Tool
Ease development and maintenance of a blazor web app server project, serving WASM as well as prerendering razor components.
Aim is to consolidate all the common services that all API projects serving WASM or MAUI applications need in secure and robust manner.
Install the nuget package for Empezar.BlazorWebAPI in your API Project.
You can also use Manager Nuget Packages to install the same.
dotnet add package Empezar.BlazorWebAPI
Register the service in Program.cs of API project.
Please note that this service already encapsulates Empezar.Cloud service. Hence, if using this package, you do not need to register Empezar.Cloud service.
var builder = WebApplication.CreateBuilder(args);
builder
//Register core services
.AddEZRBlazorWebAPI()
//Register authentication services using AzureAD and Google providers for a single tenant setup, for multi tenant setup, use AddAuthenticationMultiTenant. Register your claims.
.AddAuthenticationSingleTenant<Users, UsersReadParams>((user, claims) =>
{
claims.Add(new(ClaimTypes.Name, user.uname));
})
.AddScoped<IFormFactor, FormFactor>()
//Register UI services to prerender razor components in your SharedUI
.AddSharedUIServices(builder.Configuration[BaseConfigConstants.KestralLoopBackAddress]!, AppPlatform.Web)
//Add Localization
.AddEZRLocalization(options => options.SupportedCultures = Constants.SupportedCultures)
//Register API project to render Razor components in InteractiveWebAssembly mode
.AddRazorComponents().AddInteractiveWebAssemblyComponents()
//Share authentication state between server and client
.AddAuthenticationStateSerialization(options => options.SerializeAllClaims = true);
var app = builder.Build();
if (app.Environment.IsDevelopment()) app.UseWebAssemblyDebugging();
//Use services and API's provided by the package. ErrorDisplay is a razor component to gracefully handle errors during prerender and show freindly error page. You will need to pass your models library to register your models with postgres for JSONB datatypes
app.UseEZRBlazorWebAPI(typeof(Users).Assembly)
//Use File upload API (Cloud agnostic using Empezar.Cloud)
.UseEZRFileUpload(UploadValidator)
//Use System Parameters API
.UseEZRSysParams()
//Use Injest Logs API
.UseIngestLog()
//Register your App.razor
.MapRazorComponents<App>()
.AddInteractiveWebAssemblyRenderMode()
//Register razor pages from other assemblies
.AddAdditionalAssemblies(typeof(BaseComponent).Assembly,
typeof(OneHaul.SharedUI._Imports).Assembly, typeof(OneHaul.WebClient._Imports).Assembly);
app.Run();
Configurations can be done in appSettings.config or environment valriables as shown below
"EZRBlazorWebAPI": {
"KestralLoopBackAddress": "https://localhost:5001/",
"MaxRequestBodySizeInMB": "20",
"ZeptoMailKey": "Your Zepto Account Key, which will enable sending emails",
"GGWinClientId":"Google Client Id for Windows app (if using MAUI)",
"GGWinClientSecret": "Google Client Secret for Windows app (if using MAUI)",
"GGWinCallbackPath": "Google callback path on Windows (if using MAUI)",
"GGAndClientId": "Google Client Id for Android app (if using MAUI)",
"GGAndClientSecret": "Google Client Secret for Android app (if using MAUI)",
"GGAndCallbackPath": "Google callback path on Android (if using MAUI)",
"GGMacClientId": "Google Client Id for iOS & Mac app (if using MAUI)",
"GGMacClientSecret": "Google Client Secret for iOS & Mac app (if using MAUI)",
"GGMacCallbackPath": "Google callback path for iOS & Mac app (if using MAUI)",
"JWTIss": "Your JWT Issuer",
"JWTAud": "Your JWT Audience",
"JWTKey": "Your JWT Key",
"AgGridLicenseKey": "Your AG-Grid component license key",
"Cloud": {
"Type": "AWS",
"BucketName": "your-bucket-name",
"AzureBlobConnection":"your-azure-connectionstring",
"AllowedFileTypes": [ "docx", "xlsx", "csv", "pdf", "jpeg", "jpg", "png", "zip" ]
},
"Authentications": {
"JWT": {
"Expiry": 4320
},
"Microsoft": {
"ClientId": "Your Microsoft Client Id",
"ClientSecret": "Your Microsoft Client Secret",
"Instance": "https://login.microsoftonline.com/",
"Domain": "common",
"TenantId": "common",
"CallbackPath": "/login-callback",
"CallbackPath_Win": "http://localhost",
"CallbackPath_Android": "com.empezardigital.onehaul://auth",
"CallbackPath_Mac": "http://localhost"
},
"Google": {
"ClientId": "Your Google Client Id",
"ClientSecret": "Your Google Client Secret",
}
},
"Scalar": {
"DocumentName": "DocumentName",
"Title": "Application Title",
"Theme": "Default",
"Endpoint": "apidocs"
},
"PGConnections": {
"EnableAuditLog": true
},
"RateLimiter": {
"AuthUserPermitLimit": 50,
"AuthUserWindowInSec": 10,
"UnAuthUserPermitLimit": 20,
"UnAuthUserWindowInSec": 60
},
"EZRAPIs": {
"File": {
"UploadRoles": [ "admin" ],
"DownloadRoles": [ "admin" ],
"DeleteRoles": [ "admin" ]
},
"SysParams": {
"CreateRoles": [ "admin" ],
"ReadRoles": [ "admin" ],
"UpdateRoles": [ "admin" ]
},
"Auth": {
"SignInFromSingleLocation": false,
"GetOTP": {
"BlockDomainOTP": true,
"ForDomain": "adani.com"
}
}
},
"CSPHeaders": {
"default-src": "'self'",
"script-src": "'self' 'wasm-unsafe-eval' 'nonce-{nonce}' 'sha256-QW7zjkPzGiErwRHGBPrB5pIBLJwqu7+aHJOafqD0Wfo=' ",
"style-src": "'self' 'unsafe-inline' fonts.googleapis.com",
"img-src": "'self' data: fonts.googleapis.com",
"connect-src": "'self'",
"font-src": "'self' data: fonts.googleapis.com fonts.scalar.com fonts.gstatic.com",
"object-src": "'none'",
"base-uri": "'self'",
"form-action": "'self'",
"frame-ancestors": "'none'",
"block-all-mixed-content": "",
"upgrade-insecure-requests": ""
}
}
OR
export EZRBlazorWebAPI__Cloud__Type="AWS"
export EZRBlazorWebAPI__Cloud__AzureBlobConnection="YourConnectionString"
/api endpoint and WASM application will be served on rootScalar:EndpointAppSettings Service:To share AppSettings between API and MAUI application
Authentication Services:Below services are available for Single / Multi Tenant: Login via Microsoft / Google. Validate & exchange Microsoft / Google token for application JWT Token Generate token with APIKey Other API's for OTP Authentication and Authenticator Code Logout
File Services:File Upload / Download & Delete
System Parameter Services:Use this as a master where data on a key is stored / retrieved / upserted as Json[]. Upserting single record on uin is available.
Ingest Log Service:Sync exception Logs > Warning from WASM and MAUI to Web
Check Scalar endpoint for all the API's generated by the nuget along with your created API's
Make your class related to your functionality implementing IEndpointDefinition.
With endpoints object you will now get NewEndPoint method where you can define a new endpoint and register CRUD / Custom API's easily. It uses SimpleBuilder to define dynamic query and provides the input model along with claims.
public class SampleAPI : IEndpointDefinition
{
public void MapEndpoints(WebApplication endpoints) =>
endpoints.NewEndPoint(BaseAPI.SysParams)
.CreateAPI<SysParams<object>, long>(
createBuilder: (m, c) => SimpleBuilder.Create(@$"WITH find as (
SELECT ARRAY['value', (index-1)::TEXT] as path, (contact->>'uin')::INT uin
FROM master.sysparams, jsonb_array_elements(sysvalue->'value') with ordinality arr(contact, index)
WHERE ((({m.sysvalue}::JSONB)->>'uin')::INT IS NOT NULL) AND systype = {m.systype} AND ((contact->>'uin')::INT = (({m.sysvalue}::JSONB)->>'uin')::INT)
LIMIT 1
), genuin as (
SELECT path, COALESCE(uin, nextval('sysparamsuin')) uin
FROM (SELECT path, uin, 1 ord FROM find UNION ALL
SELECT null, null, 2 ORDER BY ord LIMIT 1) a
), jpath as (
SELECT COALESCE(path, ARRAY['value', uin::TEXT]) as path, uin
FROM genuin
), updtbl as (
UPDATE master.sysparams
SET sysvalue = JSONB_SET(sysvalue, jp.path, JSONB_SET({m.sysvalue}::JSONB, '{{uin}}'::TEXT[], to_jsonb(jp.uin), true), true)
FROM jpath jp
WHERE systype = {m.systype}
)
SELECT uin FROM jpath;"),
roles: app.Configuration.GetSection("EZRBlazorWebAPI:EZRAPIs:SysParams:CreateRoles").Get<string[]>()!,
validateModel: upsertValidator,
onSuccess: onUpsertSuccess)
.ReadAPI<SysParamsReadParams, SysParams<object>>(
createBuilder: (r, c) => SimpleBuilder.Create($"SELECT * FROM master.sysparams sp WHERE systype = {r.systype}"),
roles: app.Configuration.GetSection("EZRBlazorWebAPI:EZRAPIs:SysParams:ReadRoles").Get<string[]>()!,
validateModel: readValidator,
onAfterRead: onAfterRead,
onAfterReadAsync: onAfterReadAsync)
.UpdateAPI<SysParams<object>>(
createBuilder: (m, c) => SimpleBuilder.Create($"UPDATE master.sysparams SET sysvalue = {m.sysvalue}::JSONB WHERE systype = {m.systype}"),
roles: app.Configuration.GetSection("EZRBlazorWebAPI:EZRAPIs:SysParams:UpdateRoles").Get<string[]>()!,
validateModel: updateValidator,
onSuccess: onUpdateSuccess)
.CustomAPI(
pattern: "/",
method: HttpMethod.Get,
customDelegate: (ClaimsPrincipal caller) => "Hi",
routebuilder: r => r.RequireRole("admin").WithDescription("This is real test"));
}
Manage httpClient calls easily
var response = await qurl.OnPath(Url.Path(BaseAPI.AppSettings).Query("platform", BaseConstants.CurrentPlatform.ToString()), HttpMethod.Get, logger)
.ReadAsStringAsync(CancellationToken.None);
Inject ICrypt for Encryption and Decryption across all platforms. Encrypt / Decrypt model or string cross platform.
//Encrypt
await crypt.EncryptAsync(new User() {
email = "test@test.com",
name = "Test User"
}, BaseConstants.AppConfigEncryptionKey);
//Decrypt
await crypt.DecryptAsync<User>(encryptedString);
Compress / Decompress bytes, strings, files
//Compress
await iMini.CompressAsync(byteArray);
//Decompress
await iMini.DecompressAsync(byteArray);
Import and Export excel files or razor components as PDF's or extract HTML to send as email
Create your class and inherit from Chron
, implement ExecuteBackgroundTask to register a background process. Time can be registered in the constructor.
Chron takes care that the background service should run on only 1 container in case if multiple have scaled up
Chron job in MAUI and WASM
Lazy Caching services on client side
File service for WASM and MAUI
Use components <HandsonTable /> or <AGGrid />
use DBFactory.CreateDbConnection to create connection objects. It accepts a boolean isReadOnly param to determine which connection to return (Read Only or Read/Write)
For managing Themes and Cultures across platforms
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 net10.0 is compatible. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
This package is not used by any NuGet packages.
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.2.21 | 95 | 6/5/2026 |
| 2.2.20 | 92 | 6/5/2026 |
| 2.2.19 | 110 | 5/18/2026 |
| 2.2.18 | 359 | 4/29/2026 |
| 2.2.17 | 115 | 4/22/2026 |
| 2.2.16 | 164 | 4/13/2026 |
| 2.2.15 | 123 | 4/7/2026 |
| 2.2.14 | 164 | 3/27/2026 |
| 2.2.13 | 114 | 3/27/2026 |
| 2.2.12 | 104 | 3/26/2026 |
| 2.2.11 | 112 | 3/26/2026 |
| 2.2.10 | 221 | 3/9/2026 |
| 2.2.9 | 111 | 3/9/2026 |
| 2.2.8 | 249 | 2/24/2026 |
| 2.2.7 | 158 | 2/12/2026 |
| 2.2.6 | 117 | 2/12/2026 |
| 2.2.5 | 117 | 2/11/2026 |
| 2.2.4 | 128 | 2/10/2026 |
| 2.2.3 | 122 | 2/5/2026 |
| 2.2.2 | 140 | 2/3/2026 |