9

Using .NET Core 2.0 WebApi.

I have a webapi which has many endpoints where each endpoint is handling and throwing BadRequest when it fails. As below:

if(data == null)
{
   return BadRequest("Data must not be blank.");
}

Now since these status codes are repetitive in my api, I was thinking to create a Helper method which would return BadRequest back to my API.

So I created a static helper class. But the issue here is BadRequest is part of ControllerBase and is not available in my helper class. What is the best way to create this method that would return a BadRequest.

--Updated---

I want something like this:

    public static BadRequest GetBadRequestMessage(string message)
    {
        return BadRequest(message);
    }

I have also tried as:

    public static BadRequestResult GetBadRequestMessage(string message)
    {
        return new  BadRequestResult(message);
    }

But this gives error: Severity Code Description Project File Line Suppression State Error CS1729 'BadRequestResult' does not contain a constructor that takes 1 arguments

2 Answers 2

11

You can manually initialize the action result

return new BadRequestObjectResult("error message here");

Which is basically what the ControllerBase does internally

/// <summary>
/// Creates an <see cref="BadRequestResult"/> that produces a <see cref="StatusCodes.Status400BadRequest"/> response.
/// </summary>
/// <returns>The created <see cref="BadRequestResult"/> for the response.</returns>
[NonAction]
public virtual BadRequestResult BadRequest()
    => new BadRequestResult();

/// <summary>
/// Creates an <see cref="BadRequestObjectResult"/> that produces a <see cref="StatusCodes.Status400BadRequest"/> response.
/// </summary>
/// <param name="error">An error object to be returned to the client.</param>
/// <returns>The created <see cref="BadRequestObjectResult"/> for the response.</returns>
[NonAction]
public virtual BadRequestObjectResult BadRequest(object error)
    => new BadRequestObjectResult(error);

/// <summary>
/// Creates an <see cref="BadRequestObjectResult"/> that produces a <see cref="StatusCodes.Status400BadRequest"/> response.
/// </summary>
/// <param name="modelState">The <see cref="ModelStateDictionary" /> containing errors to be returned to the client.</param>
/// <returns>The created <see cref="BadRequestObjectResult"/> for the response.</returns>
[NonAction]
public virtual BadRequestObjectResult BadRequest(ModelStateDictionary modelState)
{
    if (modelState == null)
    {
        throw new ArgumentNullException(nameof(modelState));
    }

    return new BadRequestObjectResult(modelState);
}

Source

Sign up to request clarification or add additional context in comments.

6 Comments

Do you mean returning "BadRequestObjectResult" from my helper class ? When I do this it says "it does not contain a constructor that takes 1 arguments"
@user1563677 the source code says otherwise github.com/aspnet/Mvc/blob/master/src/…
I have updated my post with the code I have tried. Not sure why its giving error. The code you shared also gives error even if I tried using it in my api controller.
@user1563677 I've shown you the methods from source. you can do just as they did in your external helper. Recheck the code in my answer and you should see where you made the mistake.
If you hover over BadRequest in your original code you will see that method does not return BadRequestResult but BadRequestObjectResult
|
1

In .net core 5 project create BadRequestConfig class in your ioc folder/class library :

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using System.Linq;

namespace Ioc
{
    public static class BadRequestConfig
    {
        // error 400 handling - remove extra fields in error model - remove if(ModelState.IsValid)
        public static IMvcBuilder AddBadRequestServices(this IMvcBuilder services)
        {
            services.ConfigureApiBehaviorOptions(options =>
            options.InvalidModelStateResponseFactory = actionContext =>
            {
                var modelState = actionContext.ModelState.Values;
                var allErrors = actionContext.ModelState.Values.SelectMany(v => v.Errors);
                return new BadRequestObjectResult(new
                {
                    StatusCode = 400,
                    Message = string.Join(" - ", allErrors.Select(e => e.ErrorMessage))
                });
            });

            return services;
        }
    }
}

Then add AddBadRequestServices() method in ConfigureServices method in your startup.cs file :

public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbServices();
        services.AddAppServices();
        services.AddControllers().AddBadRequestServices(); // here
        services.AddJwtAuthentication();
        services.AddSwaggerServices();
    }

By this solution it is not necessary to write if(ModelState.IsValid) in your actions.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.