Error handling allows a NET 8 Web API to handle unforeseen circumstances that arise during processing and provide any useful error response. Having said that, below are a few distinct approaches to error handling, along with samples for each.
1. Global Exception Handling with Middleware
You can write middleware to catch unhandled exceptions for your free application. This method is useful for consistently returning the same response in case of an error.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | <span class="token keyword keyword-public">public</span> <span class="token keyword keyword-class">class</span> <span class="token class-name">ExceptionHandlingMiddleware</span> <span class="token punctuation">{</span> <span class="token keyword keyword-private">private</span> <span class="token keyword keyword-readonly">readonly</span> <span class="token class-name">RequestDelegate</span> _next<span class="token punctuation">;</span> <span class="token keyword keyword-public">public</span> <span class="token function">ExceptionHandlingMiddleware</span><span class="token punctuation">(</span><span class="token class-name">RequestDelegate</span> next<span class="token punctuation">)</span> <span class="token punctuation">{</span> _next <span class="token operator">=</span> next<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword keyword-public">public</span> <span class="token keyword keyword-async">async</span> <span class="token return-type class-name">Task</span> <span class="token function">Invoke</span><span class="token punctuation">(</span><span class="token class-name">HttpContext</span> context<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword keyword-try">try</span> <span class="token punctuation">{</span> <span class="token keyword keyword-await">await</span> <span class="token function">_next</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword keyword-catch">catch</span> <span class="token punctuation">(</span><span class="token class-name">Exception</span> ex<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword keyword-await">await</span> <span class="token function">HandleExceptionAsync</span><span class="token punctuation">(</span>context<span class="token punctuation">,</span> ex<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword keyword-private">private</span> <span class="token keyword keyword-static">static</span> <span class="token return-type class-name">Task</span> <span class="token function">HandleExceptionAsync</span><span class="token punctuation">(</span><span class="token class-name">HttpContext</span> context<span class="token punctuation">,</span> <span class="token class-name">Exception</span> exception<span class="token punctuation">)</span> <span class="token punctuation">{</span> context<span class="token punctuation">.</span>Response<span class="token punctuation">.</span>ContentType <span class="token operator">=</span> <span class="token string">"application/json"</span><span class="token punctuation">;</span> context<span class="token punctuation">.</span>Response<span class="token punctuation">.</span>StatusCode <span class="token operator">=</span> StatusCodes<span class="token punctuation">.</span>Status500InternalServerError<span class="token punctuation">;</span> <span class="token class-name"><span class="token keyword keyword-var">var</span></span> response <span class="token operator">=</span> <span class="token keyword keyword-new">new</span> <span class="token punctuation">{</span> message <span class="token operator">=</span> <span class="token string">"An error occurred."</span><span class="token punctuation">,</span> detail <span class="token operator">=</span> exception<span class="token punctuation">.</span>Message <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword keyword-return">return</span> context<span class="token punctuation">.</span>Response<span class="token punctuation">.</span><span class="token function">WriteAsJsonAsync</span><span class="token punctuation">(</span>response<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
// Register in Program.cs
1 | app<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">UseMiddleware</span><span class="token generic class-name"><span class="token punctuation"><</span>ExceptionHandlingMiddleware<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
2. Using ExceptionFilter in Controllers
Then we have ExceptionFilter, which is action-specific for that controller only.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <span class="token keyword keyword-public">public</span> <span class="token keyword keyword-class">class</span> <span class="token class-name">CustomExceptionFilter</span> <span class="token punctuation">:</span> <span class="token type-list"><span class="token class-name">IExceptionFilter</span></span> <span class="token punctuation">{</span> <span class="token keyword keyword-public">public</span> <span class="token return-type class-name"><span class="token keyword keyword-void">void</span></span> <span class="token function">OnException</span><span class="token punctuation">(</span><span class="token class-name">ExceptionContext</span> context<span class="token punctuation">)</span> <span class="token punctuation">{</span> context<span class="token punctuation">.</span>Result <span class="token operator">=</span> <span class="token keyword keyword-new">new</span> <span class="token constructor-invocation class-name">ObjectResult</span><span class="token punctuation">(</span><span class="token keyword keyword-new">new</span> <span class="token punctuation">{</span> message <span class="token operator">=</span> <span class="token string">"Controller-level error occurred."</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> StatusCode <span class="token operator">=</span> StatusCodes<span class="token punctuation">.</span>Status500InternalServerError <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// Apply the filter on a controller</span> <span class="token punctuation">[</span><span class="token function">ServiceFilter</span><span class="token punctuation">(</span><span class="token keyword keyword-typeof">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">CustomExceptionFilter</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">]</span> <span class="token punctuation">[</span><span class="token attribute"><span class="token class-name">ApiController</span></span><span class="token punctuation">]</span> <span class="token punctuation">[</span><span class="token attribute"><span class="token class-name">Route</span><span class="token attribute-arguments"><span class="token punctuation">(</span><span class="token string">"api/[controller]"</span><span class="token punctuation">)</span></span></span><span class="token punctuation">]</span> <span class="token keyword keyword-public">public</span> <span class="token keyword keyword-class">class</span> <span class="token class-name">ProductsController</span> <span class="token punctuation">:</span> <span class="token type-list"><span class="token class-name">ControllerBase</span></span> <span class="token punctuation">{</span> <span class="token punctuation">[</span><span class="token attribute"><span class="token class-name">HttpGet</span></span><span class="token punctuation">]</span> <span class="token keyword keyword-public">public</span> <span class="token return-type class-name">IActionResult</span> <span class="token function">GetProducts</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword keyword-throw">throw</span> <span class="token keyword keyword-new">new</span> <span class="token constructor-invocation class-name">Exception</span><span class="token punctuation">(</span><span class="token string">"Something went wrong!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
3. Handling Errors in Action Methods
You can also catch exceptions within action methods (using try-catch block) for more detailed error handling.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <span class="token punctuation">[</span><span class="token attribute"><span class="token class-name">HttpGet</span><span class="token attribute-arguments"><span class="token punctuation">(</span><span class="token string">"{id}"</span><span class="token punctuation">)</span></span></span><span class="token punctuation">]</span> <span class="token keyword keyword-public">public</span> <span class="token return-type class-name">IActionResult</span> <span class="token function">GetProduct</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword keyword-int">int</span></span> id<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword keyword-try">try</span> <span class="token punctuation">{</span> <span class="token class-name"><span class="token keyword keyword-var">var</span></span> product <span class="token operator">=</span> _productService<span class="token punctuation">.</span><span class="token function">GetProductById</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>product <span class="token operator">==</span> <span class="token keyword keyword-null">null</span><span class="token punctuation">)</span> <span class="token keyword keyword-return">return</span> <span class="token function">NotFound</span><span class="token punctuation">(</span><span class="token keyword keyword-new">new</span> <span class="token punctuation">{</span> message <span class="token operator">=</span> <span class="token string">"Product not found"</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword keyword-return">return</span> <span class="token function">Ok</span><span class="token punctuation">(</span>product<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword keyword-catch">catch</span> <span class="token punctuation">(</span><span class="token class-name">Exception</span> ex<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword keyword-return">return</span> <span class="token function">StatusCode</span><span class="token punctuation">(</span><span class="token number">500</span><span class="token punctuation">,</span> <span class="token keyword keyword-new">new</span> <span class="token punctuation">{</span> message <span class="token operator">=</span> <span class="token string">"An error occurred"</span><span class="token punctuation">,</span> detail <span class="token operator">=</span> ex<span class="token punctuation">.</span>Message <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
4. Using Problem Details
Enriched problem details are a standardized way of returning error information in an enriched format (often as part of the HTTP 400 or 500 response).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <span class="token punctuation">[</span><span class="token attribute"><span class="token class-name">HttpGet</span><span class="token attribute-arguments"><span class="token punctuation">(</span><span class="token string">"{id}"</span><span class="token punctuation">)</span></span></span><span class="token punctuation">]</span> <span class="token keyword keyword-public">public</span> <span class="token return-type class-name">IActionResult</span> <span class="token function">GetProduct</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword keyword-int">int</span></span> id<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>id <span class="token operator"><=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token class-name"><span class="token keyword keyword-var">var</span></span> problemDetails <span class="token operator">=</span> <span class="token keyword keyword-new">new</span> <span class="token constructor-invocation class-name">ProblemDetails</span> <span class="token punctuation">{</span> Status <span class="token operator">=</span> StatusCodes<span class="token punctuation">.</span>Status400BadRequest<span class="token punctuation">,</span> Title <span class="token operator">=</span> <span class="token string">"Invalid Product ID"</span><span class="token punctuation">,</span> Detail <span class="token operator">=</span> <span class="token string">"The Product ID must be greater than zero."</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword keyword-return">return</span> <span class="token function">BadRequest</span><span class="token punctuation">(</span>problemDetails<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Continue with normal logic</span> <span class="token punctuation">}</span> |
5. Validation Error Handling
You can have global model validation errors, but you resolve them in a particular action. You can simply use [ApiController] and have automatic handling of model validation errors.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token keyword keyword-public">public</span> <span class="token keyword keyword-class">class</span> <span class="token class-name">Product</span> <span class="token punctuation">{</span> <span class="token punctuation">[</span><span class="token attribute"><span class="token class-name">Required</span></span><span class="token punctuation">]</span> <span class="token keyword keyword-public">public</span> <span class="token return-type class-name"><span class="token keyword keyword-string">string</span></span> Name <span class="token punctuation">{</span> <span class="token keyword keyword-get">get</span><span class="token punctuation">;</span> <span class="token keyword keyword-set">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">[</span><span class="token attribute"><span class="token class-name">Range</span><span class="token attribute-arguments"><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span></span></span><span class="token punctuation">]</span> <span class="token keyword keyword-public">public</span> <span class="token return-type class-name"><span class="token keyword keyword-decimal">decimal</span></span> Price <span class="token punctuation">{</span> <span class="token keyword keyword-get">get</span><span class="token punctuation">;</span> <span class="token keyword keyword-set">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">[</span><span class="token attribute"><span class="token class-name">HttpPost</span></span><span class="token punctuation">]</span> <span class="token keyword keyword-public">public</span> <span class="token return-type class-name">IActionResult</span> <span class="token function">CreateProduct</span><span class="token punctuation">(</span><span class="token class-name">Product</span> product<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// If model is invalid, ASP.NET automatically returns a 400 response</span> <span class="token keyword keyword-return">return</span> <span class="token function">Ok</span><span class="token punctuation">(</span><span class="token keyword keyword-new">new</span> <span class="token punctuation">{</span> message <span class="token operator">=</span> <span class="token string">"Product created successfully"</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Unlike [ApiController], when the model is invalid,. NET 8 will automatically return an error response with the details of the validation failure with a 400 status code.
6. Using ExceptionHandler for Global Error Pages
In production, UseExceptionHandler allows you to use your own custom error pages.
1 2 3 4 5 6 7 | app<span class="token punctuation">.</span><span class="token function">UseExceptionHandler</span><span class="token punctuation">(</span><span class="token string">"/error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> app<span class="token punctuation">.</span><span class="token function">Map</span><span class="token punctuation">(</span><span class="token string">"/error"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token class-name">HttpContext</span> context<span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token class-name"><span class="token keyword keyword-var">var</span></span> response <span class="token operator">=</span> <span class="token keyword keyword-new">new</span> <span class="token punctuation">{</span> message <span class="token operator">=</span> <span class="token string">"An error occurred"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword keyword-return">return</span> Results<span class="token punctuation">.</span><span class="token function">Problem</span><span class="token punctuation">(</span><span class="token named-parameter punctuation">statusCode</span><span class="token punctuation">:</span> StatusCodes<span class="token punctuation">.</span>Status500InternalServerError<span class="token punctuation">,</span> <span class="token named-parameter punctuation">detail</span><span class="token punctuation">:</span> response<span class="token punctuation">.</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;<br /></span> |
ASP.NET 8.0.8 Hosting Recommendation
ASP.NET is a powerful platform for creating web applications and services. You must be comfortable with JavaScript, HTML, CSS, and C# before developing a web application in ASP.NET. On the market, there are thousands of web hosting companies providing ASP.NET Hosting. But, only very few web hosting companies could provide high quality ASP.NET hosting solution. ASP.NET is the best development language in Windows platform, which is released by Microsoft and widely used to build all types of dynamic Web sites and XML Web services. With this article, we’re going to help you to find the best ASP.NET Hosting solution in Europe based on reliability, features, price, performance and technical support. After we reviewed about 30+ ASP.NET hosting providers in Europe, our Best ASP.NET Hosting Award in Europe goes to HostForLIFE.eu, one of the fastest growing private companies and one of the most reliable hosting providers in Europe.