Back to Examples
C# / .NET
Integrate GuardCrow into your .NET applications using HttpClient.
Basic Example
A simple example using HttpClient:
Program.cscsharp
using System.Text.Json;using System.Text.Json.Serialization;var apiKey = Environment.GetEnvironmentVariable("GUARDCROW_API_KEY");using var client = new HttpClient();client.DefaultRequestHeaders.Add("X-API-Key", apiKey);var request = new { content = "Hello, this is a test message" };var response = await client.PostAsJsonAsync("https://api.guardcrow.com/v1/analyze",request);response.EnsureSuccessStatusCode();var result = await response.Content.ReadFromJsonAsync<AnalyzeResponse>();Console.WriteLine($"Passed: {result?.Passed}, Score: {result?.Score}");public record AnalyzeResponse(bool Passed,int Score,string Sentiment,string Description,string[] Categories,[property: JsonPropertyName("processingTimeMs")] int ProcessingTimeMs);
Complete Client Class
A production-ready client with error handling and retry logic:
GuardCrowClient.cscsharp
using System.Net;using System.Net.Http.Json;using System.Text.Json;using System.Text.Json.Serialization;namespace GuardCrow;public class GuardCrowClient : IDisposable{private readonly HttpClient _client;private readonly string _baseUrl;private readonly int _maxRetries;private readonly JsonSerializerOptions _jsonOptions;public GuardCrowClient(string apiKey, string? baseUrl = null, int maxRetries = 3){_baseUrl = baseUrl ?? "https://api.guardcrow.com/v1";_maxRetries = maxRetries;_client = new HttpClient{Timeout = TimeSpan.FromSeconds(30)};_client.DefaultRequestHeaders.Add("X-API-Key", apiKey);_jsonOptions = new JsonSerializerOptions{PropertyNamingPolicy = JsonNamingPolicy.CamelCase};}public async Task<AnalyzeResponse> AnalyzeAsync(string content,Dictionary<string, string>? metadata = null,CancellationToken cancellationToken = default){var request = new AnalyzeRequest{Content = content,Metadata = metadata};Exception? lastException = null;for (int attempt = 0; attempt < _maxRetries; attempt++){try{var response = await _client.PostAsJsonAsync($"{_baseUrl}/analyze",request,_jsonOptions,cancellationToken);if (response.StatusCode == HttpStatusCode.TooManyRequests){var resetHeader = response.Headers.GetValues("X-RateLimit-Reset").FirstOrDefault();if (resetHeader != null && long.TryParse(resetHeader, out var resetTime)){var waitTime = DateTimeOffset.FromUnixTimeSeconds(resetTime) - DateTimeOffset.UtcNow;if (waitTime > TimeSpan.Zero){await Task.Delay(waitTime, cancellationToken);continue;}}await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, attempt)), cancellationToken);continue;}if (!response.IsSuccessStatusCode){var error = await response.Content.ReadFromJsonAsync<ErrorResponse>(_jsonOptions,cancellationToken);throw new GuardCrowException(error?.Error?.Code ?? "UNKNOWN",error?.Error?.Message ?? "Unknown error",(int)response.StatusCode);}var result = await response.Content.ReadFromJsonAsync<AnalyzeResponse>(_jsonOptions,cancellationToken);return result ?? throw new GuardCrowException("INVALID_RESPONSE","Failed to parse response",200);}catch (GuardCrowException ex) when (ex.Code == "INVALID_API_KEY" ||ex.Code == "CONTENT_TOO_LONG"){throw;}catch (Exception ex) when (ex is not GuardCrowException){lastException = ex;if (attempt < _maxRetries - 1){await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, attempt)), cancellationToken);}}}throw lastException ?? new GuardCrowException("MAX_RETRIES","Max retries exceeded",0);}public async Task<bool> HealthCheckAsync(CancellationToken cancellationToken = default){var response = await _client.GetAsync($"{_baseUrl}/health", cancellationToken);return response.IsSuccessStatusCode;}public void Dispose() => _client.Dispose();}public class AnalyzeRequest{public required string Content { get; set; }public Dictionary<string, string>? Metadata { get; set; }}public class AnalyzeResponse{public bool Passed { get; set; }public int Score { get; set; }public string Sentiment { get; set; } = "";public string Description { get; set; } = "";public string[] Categories { get; set; } = [];[JsonPropertyName("processingTimeMs")]public int ProcessingTimeMs { get; set; }}public class ErrorResponse{public ApiError? Error { get; set; }}public class ApiError{public string Code { get; set; } = "";public string Message { get; set; } = "";public int Status { get; set; }}public class GuardCrowException : Exception{public string Code { get; }public int StatusCode { get; }public GuardCrowException(string code, string message, int statusCode): base(message){Code = code;StatusCode = statusCode;}}
Using the Client
Program.cscsharp
using GuardCrow;var apiKey = Environment.GetEnvironmentVariable("GUARDCROW_API_KEY")?? throw new InvalidOperationException("API key not set");using var client = new GuardCrowClient(apiKey);try{// Simple analysisvar result = await client.AnalyzeAsync("Hello, this is a test message");Console.WriteLine($"Passed: {result.Passed}");Console.WriteLine($"Score: {result.Score}");Console.WriteLine($"Sentiment: {result.Sentiment}");// With metadatavar resultWithMeta = await client.AnalyzeAsync("Check this content",new Dictionary<string, string>{["source"] = "user-comments",["user_id"] = "user_123"});Console.WriteLine($"Description: {resultWithMeta.Description}");}catch (GuardCrowException ex){Console.WriteLine($"API Error: {ex.Code} - {ex.Message}");}
ASP.NET Core Integration
Register the client with dependency injection:
Program.cscsharp
using GuardCrow;var builder = WebApplication.CreateBuilder(args);// Register GuardCrow clientbuilder.Services.AddSingleton(_ =>{var apiKey = builder.Configuration["GuardCrow:ApiKey"]?? throw new InvalidOperationException("GuardCrow API key not configured");return new GuardCrowClient(apiKey);});builder.Services.AddControllers();var app = builder.Build();app.MapControllers();app.Run();
Controller with Moderation
CommentsController.cscsharp
using GuardCrow;using Microsoft.AspNetCore.Mvc;namespace MyApp.Controllers;[ApiController][Route("api/[controller]")]public class CommentsController : ControllerBase{private readonly GuardCrowClient _contentShield;private readonly ILogger<CommentsController> _logger;public CommentsController(GuardCrowClient contentShield,ILogger<CommentsController> logger){_contentShield = contentShield;_logger = logger;}[HttpPost]public async Task<IActionResult> CreateComment([FromBody] CreateCommentRequest request){try{var moderation = await _contentShield.AnalyzeAsync(request.Content,new Dictionary<string, string>{["user_id"] = request.UserId});if (moderation.Score >= 7){return BadRequest(new{Error = "Content blocked by moderation",Reason = moderation.Description});}// Save comment to database (your logic here)return Created("", new{Status = "created",ModerationScore = moderation.Score});}catch (GuardCrowException ex){_logger.LogError(ex, "Moderation API error");// Allow content through on API errorsreturn Created("", new { Status = "created" });}}}public record CreateCommentRequest(string Content, string UserId);
Action Filter for Auto-Moderation
Create a reusable action filter for automatic content moderation:
ModerationFilter.cscsharp
using GuardCrow;using Microsoft.AspNetCore.Mvc;using Microsoft.AspNetCore.Mvc.Filters;namespace MyApp.Filters;[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]public class ModerateContentAttribute : Attribute, IAsyncActionFilter{public string ContentProperty { get; set; } = "Content";public int MaxScore { get; set; } = 6;public async Task OnActionExecutionAsync(ActionExecutingContext context,ActionExecutionDelegate next){var contentShield = context.HttpContext.RequestServices.GetRequiredService<GuardCrowClient>();// Find content in action argumentsstring? content = null;foreach (var arg in context.ActionArguments.Values){if (arg is null) continue;var prop = arg.GetType().GetProperty(ContentProperty);if (prop?.GetValue(arg) is string value){content = value;break;}}if (string.IsNullOrEmpty(content)){await next();return;}try{var result = await contentShield.AnalyzeAsync(content);if (result.Score > MaxScore){context.Result = new BadRequestObjectResult(new{Error = "Content blocked by moderation",Reason = result.Description,Score = result.Score});return;}// Store result for use in actioncontext.HttpContext.Items["ModerationResult"] = result;}catch (GuardCrowException){// Allow through on API errors}await next();}}// Usage on a controller action[HttpPost][ModerateContent(ContentProperty = "Content", MaxScore = 6)]public IActionResult CreatePost([FromBody] CreatePostRequest request){var moderation = HttpContext.Items["ModerationResult"] as AnalyzeResponse;// Your logic herereturn Ok();}
Minimal API Example
Program.cscsharp
using GuardCrow;var builder = WebApplication.CreateBuilder(args);builder.Services.AddSingleton(_ => new GuardCrowClient(builder.Configuration["GuardCrow:ApiKey"]!));var app = builder.Build();app.MapPost("/moderate", async (GuardCrowClient client,ModerateRequest request) =>{try{var result = await client.AnalyzeAsync(request.Content);return Results.Ok(new{result.Passed,result.Score,result.Sentiment,result.Description});}catch (GuardCrowException ex){return Results.Problem(title: ex.Code,detail: ex.Message,statusCode: ex.StatusCode);}});app.Run();record ModerateRequest(string Content);
Configuration
Add your API key to appsettings.json or environment variables:
appsettings.jsonjson
{"GuardCrow": {"ApiKey": "sk_live_your_api_key_here"}}
Or use an environment variable:
Terminalbash
# Windowsset GUARDCROW_API_KEY=sk_live_your_api_key_here# Linux/macOSexport GUARDCROW_API_KEY=sk_live_your_api_key_here