Required Query String Parameters in ASP.NET Core

Cenk 956 Reputation points
2023-03-30T12:26:48.4766667+00:00

Hello guys,

I am trying to set the query string parameters required like below;

        [Authorize]
        [HttpGet]
        [ProducesResponseType(typeof(ReconciliationResponseDto),StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [ProducesResponseType(StatusCodes.Status401Unauthorized)]
        [ProducesResponseType(StatusCodes.Status500InternalServerError)]
        [ProducesResponseType(StatusCodes.Status418ImATeapot)]
        [Route("reconciliation")]
        public async Task<IActionResult> GameReconciliation([FromQuery] ReconciliationDto reconciliationDto)
        {
            using var recon = await _services.GameReconciliation(reconciliationDto);
            ...

Here is the DTO;

public class ReconciliationDto
    {
        /// <summary>
        /// Reconciliation Start Date.
        /// </summary>
        /// <example>2023-03-13</example>
        [BindRequired]
        //[Required(ErrorMessage = "Please add Reconciliation Start Date to the request.")]
        [DataType(DataType.Date)]
        public DateTime StartReconDateTime { get; set; }
        /// <summary>
        /// Reconciliation End Date.
        /// </summary>
        /// <example>2023-03-29</example>
        [BindRequired]
        //[Required(ErrorMessage = "Please add Reconciliation End Date to the request.")]
        [DataType(DataType.Date)]
        public DateTime EndReconDateTime { get; set; }
        /// <summary>
        /// Status of the purchased online game.
        /// </summary>
        /// <example>1</example>
        [BindRequired]
        //[Required(ErrorMessage = "Please enter: 1-Confirm, 2-Cancel")]
        [Range(1, 2, ErrorMessage = "Please enter: 1-Confirm, 2-Cancel")]
        public int Status { get; set; }
    }

But I am getting 500 instead of 400 Bad request. How can I fix this so that it validates the query string parameters?

User's image

I think it is due to this;

builder.Services.Configure<ApiBehaviorOptions>(options
    => options.SuppressModelStateInvalidFilter = true);

When I remove this code above the response is like this;

{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
    "title": "One or more validation errors occurred.",
    "status": 400,
    "traceId": "00-59c4e66ac35ef0d009dc4760b72cc968-d8a263a291fa3401-00",
    "errors": {
        "Status": [
            "A value for the 'Status' parameter or property was not provided."
        ],
        "EndReconDateTime": [
            "A value for the 'EndReconDateTime' parameter or property was not provided."
        ]
    }
}

But I just want to display errors not the type, title traceId.

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,156 questions
{count} votes

3 answers

Sort by: Most helpful
  1. AgaveJoe 26,191 Reputation points
    2023-03-30T15:10:53.0333333+00:00

    I assume your code throws an exception. Did you try setting a breakpoint to debug your code? Did you check if the ModelState is valid?

    Anyway, the following works.

            [HttpGet]
            [ProducesResponseType(typeof(ReconciliationDto), StatusCodes.Status200OK)]
            public IActionResult Get([FromQuery]ReconciliationDto dto)
            {
                if(!ModelState.IsValid)
                {
                    return BadRequest(ModelState);
                }
                return Ok(dto);
            }
    

  2. Bruce (SqlWork.com) 55,601 Reputation points
    2023-03-30T20:08:47.84+00:00

    you would need to write middleware or action filter that detected the 400 response and replaced with your own response object.

    https://learn.microsoft.com/en-us/aspnet/core/web-api/handle-errors?view=aspnetcore-7.0

    0 comments No comments

  3. Qing Guo - MSFT 886 Reputation points Microsoft Vendor
    2023-03-31T02:35:55.0333333+00:00

    Hi @Cenk,

    I just want to display errors not the type, title traceId.

    I have a work demo like below, you can refer to it.

    1. Create a static class with method like:
        public static class InvalidModelStateResponse
            {
                public static IActionResult MakeValidationResponse(ActionContext context)
                {
                    var Details = new ValidationProblemDetails(context.ModelState)
                    {
                        Status = StatusCodes.Status400BadRequest,
                    };
                   
                    var errorDetails = new ErrorDetails
                    {
                        Status = Details.Status,
                        Errors = Details.Errors,
                    };
        
                    var result = new BadRequestObjectResult(errorDetails);
                    result.ContentTypes.Add("application/json");           
                    return result;
                }
            }
            
    

    2.Create a class for the response:

    public class ErrorDetails
    {
        public int? Status { get; set; }
        public IDictionary<string, string[]> Errors { get; set; }
    }
    

    3.Add the following code in the Program.cs:

    builder.Services.AddControllers().ConfigureApiBehaviorOptions(options =>
    
    {options.InvalidModelStateResponseFactory = InvalidModelStateResponse.MakeValidationResponse;});
    

    4.result:

    User's image


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best regards,

    Qing Guo

    0 comments No comments