Magnus Mårtensson
Microsoft Regional Director, Azure MVP, CEO Loftysoft
Avirag Jain
Director & CTO R Systems
Mahesh Chand
Founder C# Corner, CEO Mindcracker
Chris Gali
CEO & Co-Founder Graphite
Subinder Khurana
Chief Architect StoryProcess, Founder NASSCOM DeepTech Club
Bryan Rishforth
Investor, Chairman Graphite
Bryn Everson
Director Biz Dev Graphite
Raj Tiwari
Digital Transformation Leader, Futurist and Visionary
Joseph Guadagno
Microsoft MVP, Lead Quicken Loans
Nikita Sachdev
Entrepreneur, Blockchain Enthusiast & Advisor, Social Media Influencer
Doug Wagner
COO & Founder Adapt Technical Group
Ritesh Modi
Architect, Senior Evangelist, Cloud Architect
Crystal Wenrick
Director Communications Mindcracker
Allen O’Neill
Microsoft MVP, Consulting Engineer/Architect
Praveen Kumar
CEO MCN Solutions
Chris Love
Founder Love2Dev, Microsoft MVP, Author
Sanjay Vyas
Microsoft Regional Director, Microsoft MVP, Founder & CEO SkillLabs Technologies
Veena Sarda
Deep Learning Consultant, Author
Sekhar Srinivasan
C# Corner MVP, Microsoft Certified Trainer, Pluralsight Author
Lalit Bansal
Founder & CEO - EIY SYS
Navdeep Garg
CEO Revinfotech
Prakash Tripathi
Tech Manager/Leader, Microsoft MVP, Blogger
Bhavna Jain
Breakthrough Consultant
Naveen Sharma
Enterprise Architect, Leadership Coach, Author
Vidya Vrat Agarwal
Principal Architect, Microsoft MVP, Author
Sheetal Agarwal
Founder Clownselors, Medical Clown, Trainer
Abhishek Kant
Founder GTM Catalyst
Vishnu Saran
Founder & CEO VoiceQube
Sandeep Soni
Founder & CEO Deccansoft, Microsoft Certified Trainer
Parveen Malik
AVP InfoSec & Vulnerability Management, Information Security Expert
Nitin Pandit
Microsoft MVP, Developer Evangelist, Author
Niloshima Srivastava
C# Corner MVP, Tech Architect, Trainer, Blogger
Bala Chirtsabesan
Senior Software Engineer at Microsoft, Author
Manoj Mittal
Sr. Technical Architect, C# Corner MVP, Author
Chandni Di
Co-Founder Voice of Slum
Vithal Wadje
Technical Lead, Microsoft MVP, Author
Shivam Ahuja
Founder SkillCircle, Business Mentor
Chervine Bhiwoo
Solution Architect, Microsoft MVP, Author
Saurabh Jain
Vice President Paytm, Founder Fun2Do Labs, Author
Vinay Solanki
Head IoT at Lenovo, Founder IoT-NCR
Anshu kumari
Founder Blockchainkids, Inventor, Trainer
Amit Singal
CEO Startup Buddy
Dev Pratap
Co-Founder & CEO Voice of Slum
Amey Vartak
Technology Consultant, Full Stack Developer, C# Corner MVP, Author
Viswanatha Swamy
Principal Software Engineer, C# Corner MVP, Author
Sanket Verma
Research Engineer @ Ballistics (Forensics) and Chair, PyData Delhi
Sourabh Somani
Lead Developer, Microsoft MVP, Author
Abhishek Mishra
Software Architect, C# Corner MVP, Author
Siddharth Vaghasia
Technical Consultant, C# Corner MVP, Blogger
Bassam Alugili
Senior Software Specialist, Database Expert
S Ravi Kumar
Solution Architect, C# Corner MVP, Author
Sundaram Subramanian
Full Stack Developer, C# Corner MVP, Speaker
Deepesh Somani
Solution Architect, Microsoft MVP, Author
Debasis Saha
Technical Project Manager, C# Corner MVP, Blogger, Author
Vipul Jain
Software Architect, C# Corner MVP, Author
Akshay Patel
Technical Architect, Microsoft Certified Trainer, C# Corner MVP, Author
Stephen Simon
RPA Developer, Evangelist, Author
Vivek Sharma
Founder Kingster636, AR/VR Specialist
Jeetendra Gund
Technical Lead, C# Corner MVP, Author
Sujal Beniwal
AI Enthusiast, Student
M Viknaraj
Microsoft MVP, Azure Architect, Author
Prasham Sabadra
Software Architect, C# Corner MVP, Trainer, Author
Aakash Maurya
Senior Developer, C# Corner MVP, Speaker
Ankit Sharma
Senior Software Engineer, C# Corner MVP, Author
Mangesh Gaherwar
Team Lead, C# Corner MVP, Author
Viral Jain
Technical Consultant, C# Corner MVP, Author
Bhasker Das
Solution Architect, Evangelist
Manish Dwivedi
Associate Project Manager
Ck Nitin
Programmer, Author
Rohit Gupta
Technical Trainer, Author
Manish Tewatia
Full-stack Marketer, UX Designer
Bhavya Gaur
Technical Illustrator
Rohit Tomar
SEO/SMO Expert
Web Track
Cloud & Data Track
Dev Track
Registration & Breakfast
Future of Desktop Apps with JS (ElectronJs)
Nitin Pandit
Building Serverless Microservices Using Microsoft Azure
Vithal Wadje
Innovating RPA: A Robot for Every Person
Stephen Simon
Managing Cloud Storage Accounts using Logic Apps
Viknaraj Manogararajah
Data visualization using Python
Sekhar Srinivasan
Going Cross platform with AR Foundation
Vivek Sharma
Keynote
Managing your Azure dependencies in ASP.NET Core apps using VS
Bala Chirtsabesan
Securing Applications on Intelligent Azure
Abhishek Mishra
Getting started with Blazor the Framework of Future
S Ravi Kumar
Lunch
Build Progressive Web Apps using Angular 9
Debasis Saha
Build and deploy to any platform using Azure DevOps
Chervine Bhiwoo
Deep Dive in Azure Service Bus
Akshay Patel
Build a Native Mobile Application using React Native and JavaScript
Joseph Guadagno
Making sense of Web Job, Web Job SDK and Functions in Azure
Prakash Tripathi
CloudFront Distribution in AWS
Viral Jain
Tea Break
Introduction to PowerBI
Aakash Maurya
Build Advanced SPFx solutions with React and Graph API
Siddharth Vaghasia
Build Business Intelligence Analyst (BIA) Skills
Sundaram Subramanian
Deep dive of Power Platform – AI BUILDER
Prasham Sabadra
Panel 1
What's new in SharePoint development
Vipul Jain
Build a SSO (Single Sign On) based Native JavaScript application with Microsoft Identity within 10 minutes
Manoj Mittal
Panel 2
Applications and working of AI
Veena Sarda
Deploying serverless API's with .Net core 3.0 on AWS & Azure
Amey Vartak
Panel 3
Blockchain with .NET Core (Ark)
Anshu Kumari
Closing Note & Prize Distribution
Dev Track
Cloud Track
Architecture Track
Emerging Tech Track
Registration & Breakfast
Creating Full-Stack Web Apps Using Server-Side Blazor
Ankit Sharma
Real time face recognition with MS Cognitive Services
Niloshima Srivastava
Building Scalable APIs with GraphQL
Jeetendra Gund
Future of development with AI and Blockchain
Navdeep Garg
Debugging Tips and Tricks with Visual Studio 2019
Joseph Guadagno
Azure Containers
Abhishek Kant
Enterprise Architecture
Naveen Sharma
Bot Framework - learn it fast and look like a boss!
Allen O’Neill
Keynote
.Net Core & C# 8 Performance
David McCarter
Working with Azure kubernetes services
Ritesh Modi
Becoming an Architect
Vidyavrat Agarwal
Why Techies Need to Learn Product Management
Saurabh Jain
Lunch
Build a rules engine in .Net Core
Sanjay Vyas
Building CI and CD Pipeline using Azure DevOps
Sandeep Soni
Entity Framework Core - Tips and Tricks, Performance Optimization, and Tuning
Bassam Alugili
Hacking your way into Data Science
Sanket Verma
Speed up your .Net Core Website
Sourabh Somani
Azure
Magnus Mårtensson
Demystifying Open Distro for Elasticsearch
Suman Debnath
Future of Data
Shivam Ahuja
Tea Break
gRPC with C# and .Net Core
Mangesh Gaherwar
Panel 1
Essentials of Cloud security
Parveen Malik
Power platform and Dynamics 365
Deepesh Somani
Microservices - the gRPC Way
Viswanatha Swamy
Panel 2
Reserved
Reserved
Closing Note & Prize Distribution
Building a Custom Health Check for Azure SQL in ASP.NET Core
Modern distributed applications rely on rapid feedback to know when a dependency is failing, and that requirement is especially sharp for teams running workloads on Microsoft Azure. Whether the system is hosted on Azure App Service in Sydney, deployed to AKS clusters in Melbourne, or sitting behind an Application Gateway in Brisbane, knowing whether the data tier is reachable can mean the difference between a quick self-healing restart and a customer-visible outage. ASP.NET Core ships with a flexible diagnostics layer called Microsoft.Extensions.Diagnostics.HealthChecks, and it provides a clean extension point for plugging in domain-specific probes against external services. That extension point is the most practical place to add a tailored Azure SQL Database check, because the built-in helpers do not capture every nuance of a managed cloud database.
This article walks through the process of designing, coding, registering, and exposing a custom health check that targets Azure SQL Database, including the probe logic, transient error handling, and the response writer that turns raw results into something useful for dashboards. Along the way the discussion stays grounded in realities familiar to Australian engineering teams — data residency under the Privacy Act, the Essential Eight maturity model promoted by the Australian Cyber Security Centre, and the way Microsoft Azure Australia regions (Australia East and Australia Southeast) are commonly paired for disaster recovery. The end goal is a small, well-tested component that integrates cleanly with Kubernetes liveness and readiness probes, Azure Monitor, and any external uptime monitor.
The Health Checks Stack in ASP.NET Core
The diagnostics namespace was introduced in .NET Core 2.2 and has matured significantly since then. At its core sits the IHealthCheck interface, which exposes a single async method that returns a HealthCheckResult. The result carries a HealthStatus enum value (Healthy, Degraded, or Unhealthy), an optional description, and an exception when something has gone wrong. The framework aggregates the results from every registered check, applies any configured failure status, and writes the aggregated state to the configured endpoint.
Several extension methods make common scenarios quick to wire up. AddDbContextCheck covers Entity Framework Core contexts, AddSqlServer is meant for raw SQL Server instances, and AddAzureBlobStorage, AddRedis, and AddRabbitMQ cover other managed services. AddSqlServer under the hood simply opens a connection and executes SELECT 1, which is enough as a smoke test but does not account for Azure SQL-specific concerns such as elastic pool saturation, serverless pause behaviour, or transparent data encryption state. That gap is the reason most teams operating production workloads in Australia end up rolling their own implementation, then registering it alongside the built-in checks.
Why Azure SQL Asks for a Bespoke Probe
Azure SQL Database is not the same product as a self-managed SQL Server, even though the wire protocol is identical. Each logical server sits behind a regional gateway, pools resources inside an elastic pool or a serverless compute tier, and exposes throttling logic that can return error codes such as 10928 or 10929 when limits are hit. A simple SELECT 1 succeeds even when the database is in a paused state on a serverless tier or when the elastic pool has no available DTUs, which is why treating that query as the sole indicator of health can produce false positives.
Local context matters too. Australian regulations such as the Notifiable Data Breaches scheme under the Privacy Act 1988 push engineering teams toward observability that records not just whether a database is up, but whether recent queries are completing inside an acceptable window. A team running a payments service hosted out of Australia East and failing over to Australia Southeast for a Sydney–Melbourne active-active design needs its health probe to confirm round-trip latency, not just connectivity. Encoding that knowledge in a custom IHealthCheck is the cleanest way to surface the right signal to the platform.
Implementing the IHealthCheck Class
The first step is a class that implements IHealthCheck. The constructor receives the configuration and any injected collaborators, while CheckHealthAsync carries the probe logic. The skeleton typically looks like a small class registered through dependency injection, accepting an IConfiguration root to read the connection string and an optional ILogger for structured logging.
public sealed class AzureSqlHealthCheck : IHealthCheck
{
private readonly string _connectionString;
private readonly TimeSpan _commandTimeout;
private readonly ILogger<AzureSqlHealthCheck> _logger;
public AzureSqlHealthCheck(IConfiguration configuration, ILogger<AzureSqlHealthCheck> logger)
{
_connectionString = configuration.GetConnectionString("AzureSql")
?? throw new InvalidOperationException("AzureSql connection string missing.");
_commandTimeout = TimeSpan.FromSeconds(
configuration.GetValue<int?>("HealthChecks:AzureSql:CommandTimeoutSeconds") ?? 3);
_logger = logger;
}
public async Task<HealthCheckResult> CheckHealthAsync(
HealthCheckContext context, CancellationToken cancellationToken = default)
{
try
{
await using var connection = new SqlConnection(_connectionString);
await connection.OpenAsync(cancellationToken);
await using var command = connection.CreateCommand();
command.CommandText = "SELECT 1";
command.CommandTimeout = (int)_commandTimeout.TotalSeconds;
await command.ExecuteScalarAsync(cancellationToken);
return HealthCheckResult.Healthy("Azure SQL reachable.");
}
catch (SqlException ex) when (IsTransient(ex))
{
_logger.LogWarning(ex, "Transient Azure SQL failure during health probe.");
return HealthCheckResult.Degraded("Azure SQL transient failure.", ex);
}
catch (Exception ex)
{
_logger.LogError(ex, "Azure SQL probe failed.");
return HealthCheckResult.Unhealthy("Azure SQL probe failed.", ex);
}
}
private static bool IsTransient(SqlException ex) =>
SqlClientRetryLogic.IsTransient(ex) || ex.Number is 10928 or 10929 or 4060;
}
The probe deliberately distinguishes between Degraded and Unhealthy so that Kubernetes liveness probes are not restarted for transient hiccups. Structured logging through ILogger means the events flow naturally into Application Insights and on to dashboards reviewed by Sydney-based SREs during the morning AEST handover. IsTransient catches throttling errors, while general exceptions — including login failures, network resets, and certificate validation issues — are treated as Unhealthy.
Handling Transient Errors and Measuring Latency
A custom probe should not stop at connectivity. Capturing the elapsed time against the database is a cheap way to detect slowdowns that may indicate an overloaded elastic pool. Wrapping the call in a Stopwatch and attaching the elapsed milliseconds as data on the HealthCheckResult helps dashboards chart response time alongside availability. The trick is to keep the probe cheap enough that thousands of instances polling every few seconds do not pressure the gateway.
Polly is the standard tool for handling transient errors around the probe, and Microsoft.Data.SqlClient ships with a configurable retry provider that uses similar rules. Wrapping the OpenAsync and ExecuteScalarAsync calls inside an AsyncRetryPolicy with a couple of attempts and an exponential back-off protects the probe from being misled by a single packet drop, while still completing inside the liveness interval. For Australian deployments crossing regions to a secondary in Australia Southeast, setting the connection's Connect Timeout explicitly and bounding it to roughly two seconds keeps the entire probe inside a five-second budget.
Registering, Tagging, and Exposing the Endpoint
With the check implemented, the next step is registration inside Program.cs. The AddHealthChecks().AddCheck<>() call wires the type into the DI container, while tags separate liveness from readiness. Kubernetes typically polls /healthz/live for restart decisions and /healthz/ready for traffic gating, so the registration maps two endpoints with different tag filters.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHealthChecks()
.AddCheck<AzureSqlHealthCheck>(
name: "azure-sql",
failureStatus: HealthStatus.Unhealthy,
tags: new[] { "db", "ready", "sql" });
builder.Services.AddSingleton<AzureSqlHealthCheck>();
var app = builder.Build();
app.MapHealthChecks("/healthz/live", new HealthCheckOptions
{
Predicate = _ => false
});
app.MapHealthChecks("/healthz/ready", new HealthCheckOptions
{
Predicate = r => r.Tags.Contains("ready"),
ResponseWriter = HealthResponseWriter.WriteJsonAsync
});
A custom response writer that returns JSON, including the per-check status, duration, and tags, makes the endpoint useful for monitoring tools. Tools such as Pingdom, UptimeRobot, or an internal status page hosted on Azure Static Web Apps in Australia can parse the JSON and raise alerts when an individual dependency is degraded.
Observability, Alerting, and Compliance
Health endpoints only earn their keep when the data they emit reaches somewhere useful. Piping ILogger output into Application Insights gives engineers in Melbourne and Sydney a live view of probe duration, exception rates, and the times at which degradation events occur. Azure Monitor alert rules can then page an on-call engineer through SMS or a local Teams channel when three consecutive probes report Unhealthy, or when the rolling average of probe duration crosses a threshold that suggests an elastic pool is saturating.
Compliance considerations sit alongside observability. The Australian Cyber Security Centre's Essential Eight maturity model encourages application control, patching, and configuration baselines; a custom health check fits naturally as part of the configuration baseline for production web apps. The Notifiable Data Breaches scheme, meanwhile, makes it important that any probe failure that risks data exposure is logged with enough context for the security team to assess whether an assessment statement is required. Storing the probe outcomes for at least 30 days in a Log Analytics workspace in Australia East keeps the audit trail local, satisfying data residency expectations common in government and banking workloads.
Built-in vs Custom: A Quick Comparison
| Aspect | Built-in AddSqlServer | Custom AzureSqlHealthCheck |
|---|---|---|
| Probe query | Hard-coded SELECT 1 | Configurable, supports lightweight diagnostics |
| Throttling aware | No | Yes (10928, 10929, 10936, 4060) |
| Transient handling | None | Polly retry policy and Degraded status |
| Latency capture | Optional data dictionary | Stopwatch plus structured data |
| Compliance hooks | Generic description | Region, database name, pool size |
| Registration tags | Single tag | Multiple tags for live and ready |
Pre-Deployment Checklist
- Verify the connection string uses Encrypt=True and TrustServerCertificate=False, in line with ACSC guidance for production data tiers.
- Confirm the firewall rules on the Azure SQL logical server allow the App Service outbound IP range or the private endpoint subnet.
- Place the database in the Australia East region and replicate to Australia Southeast for cross-region resilience.
- Set CommandTimeout to three seconds or fewer to keep the probe inside a Kubernetes liveness window.
Tuning Tips for the Probe
- Cache the SqlConnection instance across probes if your library allows it; otherwise open and dispose per call.
- Add a counter metric for probe duration and emit it through Azure Monitor metrics.
- Use a dedicated lightweight login for the probe account with the minimum permissions required for SELECT.
- Re-test the probe locally by throttling the elastic pool to confirm that Degraded states fire correctly.
1, CBD, Maharaj Surajmal Road, Near Yamuna Sports Complex, Delhi, 110032
GENERAL QUERIES
Manish Tewatia
manish@csharpcon.com
+91-9718-431-042
TICKET QUERIES
Atul Gupta
conference@csharpcon.com
+91-9910-125-804