Skip to main content

.NET SDK

The Guardhouse .NET SDK provides a comprehensive API for integrating Guardhouse into your .NET applications, including ASP.NET Core, Console applications, and more.

Installation

NuGet Package

dotnet add package Guardhouse.SDK

Package Manager

Install-Package Guardhouse.SDK

.csproj Reference

<PackageReference Include="Guardhouse.SDK" Version="1.0.0" />

Getting Started

Initialize Client

using Guardhouse.SDK;
using Guardhouse.SDK.Models;

var client = new GuardhouseClient(new GuardhouseOptions
{
ClientId = "YOUR_CLIENT_ID",
ClientSecret = "YOUR_CLIENT_SECRET",
Domain = "YOUR_DOMAIN" // e.g., "your-tenant.guardhouse.cloud"
});

ASP.NET Core Dependency Injection

// Program.cs
using Guardhouse.SDK;
using Guardhouse.SDK.Extensions;

var builder = WebApplication.CreateBuilder(args);

// Add Guardhouse client
builder.Services.AddGuardhouseClient(options =>
{
options.ClientId = builder.Configuration["Guardhouse:ClientId"];
options.ClientSecret = builder.Configuration["Guardhouse:ClientSecret"];
options.Domain = builder.Configuration["Guardhouse:Domain"];
});

var app = builder.Build();

appsettings.json

{
"Guardhouse": {
"ClientId": "YOUR_CLIENT_ID",
"ClientSecret": "YOUR_CLIENT_SECRET",
"Domain": "your-tenant.guardhouse.cloud"
}
}

Inject Client

public class UserService
{
private readonly IGuardhouseClient _client;

public UserService(IGuardhouseClient client)
{
_client = client;
}

public async Task<User> GetUserAsync(string userId)
{
return await _client.Users.GetAsync(userId);
}
}

User Management

List Users

// Get all users (paginated)
var users = await _client.Users.GetAllAsync();

// With pagination
var users = await _client.Users.GetAllAsync(
page: 1,
perPage: 50
);

// With filtering and sorting
var users = await _client.Users.GetAllAsync(
page: 1,
perPage: 50,
email: "john.doe@example.com",
query: "john",
sort: "created_at",
order: SortOrder.Desc
);

// Access results
foreach (var user in users.Items)
{
Console.WriteLine($"{user.UserId}: {user.Name} ({user.Email})");
}

Console.WriteLine($"Total: {users.Total}");
Console.WriteLine($"Page: {users.Page} of {users.TotalPages}");

Get User by ID

var user = await _client.Users.GetAsync("usr_123456789");

Console.WriteLine($"User: {user.Name}");
Console.WriteLine($"Email: {user.Email}");
Console.WriteLine($"Created: {user.CreatedAt}");
Console.WriteLine($"Last Login: {user.LastLogin}");
Console.WriteLine($"Logins Count: {user.LoginsCount}");

Update User

var user = await _client.Users.GetAsync("usr_123456789");

// Update basic fields
user.Name = "John Updated Doe";
user.Email = "new.email@example.com";
user.PhoneNumber = "+1-555-987-6543";
user.Picture = "https://cdn.example.com/avatars/new.jpg";

// Update metadata
user.UserMetadata = new Dictionary<string, object>
{
{ "department", "Marketing" },
{ "employee_id", "EMP002" }
};

user.AppMetadata = new Dictionary<string, object>
{
{ "roles", new[] { "user", "moderator" } },
{ "permissions", new[] { "read:users", "write:users" } }
};

// Block/Unblock user
user.Blocked = false;

// Save changes
var updated = await _client.Users.UpdateAsync(user);

Create User

var newUser = new CreateUserRequest
{
Email = "new.user@example.com",
Password = "SecurePassword123!",
Name = "New User",
Connection = "Username-Password-Authentication",
EmailVerified = true,
UserMetadata = new Dictionary<string, object>
{
{ "department", "Engineering" }
}
};

var createdUser = await _client.Users.CreateAsync(newUser);

Delete User

await _client.Users.DeleteAsync("usr_123456789");

Current User Profile Management

Get Current User Profile

var currentUser = await _client.Users.GetMeAsync();

Console.WriteLine($"User ID: {currentUser.UserId}");
Console.WriteLine($"Name: {currentUser.Name}");
Console.WriteLine($"Email: {currentUser.Email}");
Console.WriteLine($"Email Verified: {currentUser.EmailVerified}");

Change Password

await _client.Users.ChangePasswordAsync(
currentPassword: "OldPassword123!",
newPassword: "NewSecurePassword123!",
confirmPassword: "NewSecurePassword123!"
);

Update Name

await _client.Users.UpdateNameAsync(
givenName: "John",
familyName: "Doe"
);

Update Email

await _client.Users.UpdateEmailAsync(
email: "new.email@example.com",
verifyEmail: true
);

Update Profile

await _client.Users.UpdateProfileAsync(new UpdateProfileRequest
{
Name = "John Updated Doe",
Nickname = "johndoe_new",
Picture = "https://cdn.example.com/avatars/new.jpg",
UserMetadata = new Dictionary<string, object>
{
{ "department", "Marketing" },
{ "location", "New York" }
}
});

Authentication

Get Access Token

var token = await _client.Authentication.GetAccessTokenAsync();

Console.WriteLine($"Access Token: {token.AccessToken}");
Console.WriteLine($"Token Type: {token.TokenType}");
Console.WriteLine($"Expires In: {token.ExpiresIn} seconds");
Console.WriteLine($"Scope: {token.Scope}");

Refresh Token

var newToken = await _client.Authentication.RefreshTokenAsync(refreshToken);

Revoke Token

await _client.Authentication.RevokeTokenAsync(accessToken);

User Login

var loginResult = await _client.Authentication.LoginAsync(new LoginRequest
{
Username = "user@example.com",
Password = "Password123!",
Connection = "Username-Password-Authentication"
});

Console.WriteLine($"Access Token: {loginResult.AccessToken}");
Console.WriteLine($"ID Token: {loginResult.IdToken}");
Console.WriteLine($"Refresh Token: {loginResult.RefreshToken}");

User Logout

await _client.Authentication.LogoutAsync(refreshToken);

Error Handling

Try-Catch Pattern

try
{
var user = await _client.Users.GetAsync("usr_123456789");
}
catch (GuardhouseApiException ex)
{
// API errors (4xx, 5xx)
Console.WriteLine($"API Error: {ex.Message}");
Console.WriteLine($"Code: {ex.Code}");
Console.WriteLine($"Status: {ex.StatusCode}");
Console.WriteLine($"RequestId: {ex.RequestId}");
}
catch (GuardhouseAuthenticationException ex)
{
// Authentication errors (invalid credentials, expired tokens)
Console.WriteLine($"Authentication failed: {ex.Message}");
}
catch (GuardhouseValidationException ex)
{
// Validation errors (invalid request data)
Console.WriteLine($"Validation failed: {ex.Message}");
foreach (var error in ex.ValidationErrors)
{
Console.WriteLine($" Field: {error.Field}");
Console.WriteLine($" Message: {error.Message}");
}
}

Custom Error Handling

public class CustomErrorHandler : IGuardhouseErrorHandler
{
public void HandleError(GuardhouseApiException exception)
{
// Log error
Logger.Error(exception, "Guardhouse API error");

// Send alert
AlertService.SendAlert(exception);
}
}

// Register custom error handler
var client = new GuardhouseClient(options, new CustomErrorHandler());

Configuration Options

Full Configuration

var options = new GuardhouseOptions
{
// Required
ClientId = "YOUR_CLIENT_ID",
ClientSecret = "YOUR_CLIENT_SECRET",
Domain = "YOUR_DOMAIN",

// Optional
ApiVersion = "v2",
Timeout = TimeSpan.FromSeconds(30),
RetryPolicy = new RetryPolicy
{
MaxRetries = 3,
Delay = TimeSpan.FromSeconds(1),
BackoffFactor = 2
},
LogLevel = LogLevel.Information,
EnableLogging = true
};

var client = new GuardhouseClient(options);

Retry Policy

var options = new GuardhouseOptions
{
ClientId = "YOUR_CLIENT_ID",
ClientSecret = "YOUR_CLIENT_SECRET",
Domain = "YOUR_DOMAIN",
RetryPolicy = new RetryPolicy
{
MaxRetries = 5,
Delay = TimeSpan.FromSeconds(2),
BackoffFactor = 2,
RetryableStatusCodes = new[] { 408, 429, 500, 502, 503, 504 }
}
};

Logging

Built-in Logging

var options = new GuardhouseOptions
{
ClientId = "YOUR_CLIENT_ID",
ClientSecret = "YOUR_CLIENT_SECRET",
Domain = "YOUR_DOMAIN",
LogLevel = LogLevel.Debug,
EnableLogging = true
};

Custom Logger

public class CustomLogger : IGuardhouseLogger
{
public void LogDebug(string message, params object[] args)
{
Console.WriteLine($"[DEBUG] {string.Format(message, args)}");
}

public void LogInformation(string message, params object[] args)
{
Console.WriteLine($"[INFO] {string.Format(message, args)}");
}

public LogWarning(string message, params object[] args)
{
Console.WriteLine($"[WARN] {string.Format(message, args)}");
}

public LogError(Exception exception, string message, params object[] args)
{
Console.WriteLine($"[ERROR] {string.Format(message, args)}");
Console.WriteLine($"Exception: {exception.Message}");
}
}

var client = new GuardhouseClient(options, new CustomLogger());

ASP.NET Core Integration

Authentication Middleware

// Program.cs
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.Authority = $"https://{builder.Configuration["Guardhouse:Domain"]}";
options.Audience = builder.Configuration["Guardhouse:Audience"];
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ClockSkew = TimeSpan.Zero
};
});

Authorization Policy

// Program.cs
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("ReadUsers", policy =>
policy.RequireClaim("scope", "read:users"));

options.AddPolicy("WriteUsers", policy =>
policy.RequireClaim("scope", "write:users"));
});

Protected Controller

[ApiController]
[Route("api/[controller]")]
[Authorize]
public class UsersController : ControllerBase
{
private readonly IGuardhouseClient _client;

public UsersController(IGuardhouseClient client)
{
_client = client;
}

[HttpGet]
[Authorize(Policy = "ReadUsers")]
public async Task<IActionResult> GetUsers()
{
var users = await _client.Users.GetAllAsync();
return Ok(users);
}

[HttpGet("{userId}")]
[Authorize(Policy = "ReadUsers")]
public async Task<IActionResult> GetUser(string userId)
{
var user = await _client.Users.GetAsync(userId);
return Ok(user);
}

[HttpPut("{userId}")]
[Authorize(Policy = "WriteUsers")]
public async Task<IActionResult> UpdateUser(string userId, [FromBody] UpdateUserRequest request)
{
var user = await _client.Users.GetAsync(userId);
user.Name = request.Name;
user.Email = request.Email;

var updated = await _client.Users.UpdateAsync(user);
return Ok(updated);
}
}

Best Practices

  1. Use Dependency Injection: Inject IGuardhouseClient where needed
  2. Configure Retry Policy: Handle transient failures gracefully
  3. Implement Logging: Enable logging for debugging and monitoring
  4. Handle Errors: Always use try-catch for API calls
  5. Use Async/Await: All SDK methods are asynchronous
  6. Dispose Client: Implement proper disposal pattern for console apps
  7. Cache Responses: Cache frequently accessed user data
  8. Validate Tokens: Always validate JWTs on your APIs

Additional Resources

Support

For issues, questions, or contributions: