Closed BlazorPlate closed 3 years ago
The ApiException
and ApiProblemDetailsException
has an overload constructor for you to pass the status code. Just set the corresponding status code for UnAuthorized
and Forbidden
. You can also if use the Unauthorized
or Forbid
object if your API returns an IActionResult
.
Here's a quick example for your reference:
//Configure AutoWrapper to use ProblemDetails Exception
app.UseApiResponseAndExceptionWrapper(new AutoWrapperOptions
{
UseApiProblemDetailsException = true
});
Then in your controller, you can do something like this:
[Route("unauth")]
[HttpGet]
public IActionResult TestUnAuthorized()
{
return Unauthorized();
}
[Route("forbid")]
[HttpGet]
public IActionResult TestForbidden()
{
return Forbid();
}
Here's an example using ApiException
:
//Configure AutoWrapper
app.UseApiResponseAndExceptionWrapper();
[Route("unauth")]
[HttpGet]
public IActionResult TestUnAuthorized()
{
throw new ApiException("Access is not authorized", Status401Unauthorized);
}
[Route("forbid")]
[HttpGet]
public IActionResult TestForbidden()
{
throw new ApiException("Access is forbidden", Status403Forbidden);
}
Thank you so much for your quick response, I really appreciate it.
This is the use case:
**[Authorize(Roles = "Admin")]**
public class UsersController : ApiController
{
}
How can I wrap the error message using Autowrapper in case the user is not authorized to access users controller?
One more question please, Can I use Autowrapper inside a service class instead of Controller class to wrap the class exceptions or it's just used only inside controllers?
AutoWrapper
should automatically handle unauthorized access when using the Authorize
attribute.
For example, using the default settings will result to something like this:
{
"isError": true,
"responseException": {
"exceptionMessage": "Request denied. Unauthorized access."
}
}
Using Problem Details with UseApiProblemDetailsException = true
will result to something like this:
{
"isError":true,
"type":"https://httpstatuses.com/401",
"title":"Unauthorized",
"status":401,
"detail":"",
"instance":"/api/v1/persons",
"extensions":{}
}
Can I use Autowrapper inside a service class instead of Controller class to wrap the class exceptions
No. It's meant for ASP.NET Core APIs only. However, you can use AutoWrapper.Server to unwrap the result from AutoWrapper
from any .NET clients.
Thank you for the clarification.
I tried your example with Authorize Attribute and it works as expected.
Regarding exception handling from a class library project. I'm already using AutoWrapper in a service class to catch and wrap some errors like the example below:
var result = await _roleManager.CreateAsync(role);
if (!result.Succeeded)
{
throw new ApiProblemDetailsException(result.Errors.ToApplicationError());
}
Notice result.Errors.ToApplicationError() which returns ModelStateDictionary that can be sent as a parameter to ApiProblemDetailsException.
Without adding AutoWrapper inside a class library project, how could we handle ModelStateDictionary errors?
Generally, Model state validation should be handled in the Controller level. To reference ModelStateDictionary
, you have to install Microsoft.AspNetCore.Mvc
package.
Thank you for your assistance. You are right, I ended up with looping ModelStateDictionary errors and wrapping them using stringBuilder as multiple lines string and then send it as regular exception.
How can I wrap UnAuthorized and Forbid exceptions?