Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How can I hide System.Exception errors on .NET Core?

I try to improve myself with .NET Web API now and I am trying to return a custom error in Swagger. But when returning this custom error, I can see the error is on which line. How can I do to prevent this?

public async Task<BookCreateDTO> CreateBook(BookCreateDTO bookCreateDto)
        {
            if (await _context.Books.AnyAsync(x => x.Name == bookCreateDto.Name))
            {
                throw new BookExistException("Book already exist");
            }

            var book= _mapper.Map<Book>(bookCreateDto);
            _context.Books.Add(book);
            await _context.SaveChangesAsync();
            return book;
        }

What should I do to see only this exception message in the Swagger response?
Thank you for your help.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Exceptions should be exceptional: Don’t throw exceptions for non-exceptional errors.

I don’t recommend specifying your web-service’s response DTO type in the C# action method return type because it limits your expressiveness (as you’re discovering).

  • Instead use IActionResult or ActionResult<T> to document the default (i.e. HTTP 2xx) response type and then list error DTO types in [ProducesResponseType] attributes with their corresponding HTTP status codes.
    • This also means that each response status code should only be associated with a single DTO type. This is a limitation of Swagger (which does not allow you to say "if the response status is HTTP 200 then the response body/DTO is one-of DtoFoo, DtoBar, DtoQux", unfortunately)
  • For error conditions, add the errors to ModelState (with the Key, if possible) and let ASP.NET Core handle the rest for you with ProblemDetails.
  • Document the DTOs used, and their corresponding HTTP status codes, with [ProducesResponseType]: this is very useful when using Swagger/NSwag to generate online documentation and client libraries.
  • Also: do not use EF entity types as DTOs or ViewModels.
    • The main reason is that when the response is serialized, entities with lazy-loaded properties will cause your entire database object-graph to be serialized (bad!)
    • Another reason is security: if you directly accept an EF entity as an input request body DTO or HTML form model then users/visitors can set properties arbitrarily, e.g. POST /users with { accessLevel: 'superAdmin' }, for example.
    • Another is intent: an entity-type is for in-proc state, not as a communications contract.
[ProducesResponseType(typeof(BookCreateDTO), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status409Conflict)]
public async Task< ActionResult<BookCreateDTO> > CreateBook( [FromBody] BookCreateDTO bookCreateDto )
{
    // Does a book with the same name exist? If so, then return HTTP 409 Conflict.
    if( await _context.Books.AnyAsync(x => x.Name == bookCreateDto.Name) )
    {
        this.ModelState.Add( nameof(BookCreateDTO.Name), "Book already exists" );
        BadRequestObjectResult conflictResult = this.BadRequest( this.ModelState );
        // `BadRequestObjectResult` is HTTP 400 by default, change it to HTTP 409:
        conflictResult.StatusCode = 409;
        return conflictResult;
    }

    Book addedBook;
    {
        addedBook = this.mapper.Map<Book>( bookCreateDto );
        _ = this.context.Books.Add( book );
        _ = await this.context.SaveChangesAsync();
    }

    BookCreateDTO responseDto = this.mapper.Map<BookCreateDTO >( addedBook );

    return this.Ok( responseDto );
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading