77

I was wondering if it was possible to return a bad request with content from an MVC Controller? The only way I have been able to do this is to throw HttpException however here I can't set any content. Tried this approach to but for some odd reason I am always getting an OK back. Is it possible to do this?

public class SomeController : Controller
{
    [HttpPost]
    public async Task<HttpResponseMessage> Foo()
    {
        var response = new HttpResponseMessage(HttpStatusCode.BadRequest);
        response.Content = new StringContent("Naughty");

        return response;    
    }
}
ekad
  • 14,436
  • 26
  • 44
  • 46
Dr Schizo
  • 4,045
  • 7
  • 38
  • 77

7 Answers7

126
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "naughty");
Ian
  • 2,898
  • 1
  • 27
  • 29
  • 12
    just a side note for people coming here these days: this constructor signature does not seem to be available in latest Asp.Net MVC 6 ... at least for Asp.Net Core 1 RC1 – superjos May 25 '16 at 20:54
  • I faced the issue where returning BadRequest was giving error. The solution was to inherit the API class from ControllerBase class – hozefam Jan 15 '22 at 16:02
29

Set the Http status code to bad request and use Content method to send your content along with response.

public class SomeController : Controller
{
    [HttpPost]
    public async Task<ActionResult> Foo()
    {
        Response.StatusCode = 400;
        return Content("Naughty");
    }
}
ShankarSangoli
  • 69,612
  • 13
  • 93
  • 124
  • 1
    This (setting `Response.StatusCode`) worked for me. As @superjos mentioned above, that constructor doesn't seem to be around anymore. – Jedidja Jun 01 '18 at 15:24
17

In addition to the @Ekk's answer, make sure to check this:

ASP.NET+Azure 400 Bad Request doesn't return JSON data

Add the following entry to your 'web.config'.

 <system.webServer>
    <httpErrors existingResponse="PassThrough"/>
 </system.webServer>

...

Masood Khaari
  • 2,911
  • 2
  • 23
  • 40
  • 1
    This is the best answer. I could not send anything from mvc controller exception, but this enabled it. – Alexander Jun 18 '20 at 14:44
9

Of course you can.

Take a look at my Action

// GET: Student/Details/5
public ActionResult Details(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    Student student = db.Students.Find(id);
    if (student == null)
    {
        return HttpNotFound();
    }
    return View(student);
}

I think this is best practice

  1. to return HttpStatusCodeResult(HttpStatusCode.BadRequest); in case user does not provided a required value

  2. to return HttpNotFound(); in case the user provided a required value but not veiled

hope this help you

Nathan Smith
  • 8,271
  • 3
  • 27
  • 44
Basheer AL-MOMANI
  • 14,473
  • 9
  • 96
  • 92
4

You can pass in error message to the second parameter like so:

return new HttpResponseMessage(HttpStatusCode.BadRequest, "Your message here");
Thom
  • 663
  • 7
  • 19
Ekk
  • 5,627
  • 19
  • 27
  • 3
    Doing the above returns me back a 200 for some odd reason. I tried this using both a rest client, i.e. postman and via the angularjs http dependency. – Dr Schizo Jul 08 '15 at 09:17
1

The TrySkipIisCustomErrors flag can be used to turn off IIS custom error handling.

[HttpGet]
public void Foo()
{
  HttpContext.Response.TrySkipIisCustomErrors = true;
  HttpContext.Response.StatusCode = 400;
  HttpContext.Response.Write("Naughty");
}
  • 5
    While this code snippet may solve the question, [including an explanation](//meta.stackoverflow.com/questions/114762/explaining-entirely-code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. Please also try not to crowd your code with explanatory comments, this reduces the readability of both the code and the explanations! – Filnor May 14 '20 at 09:53
1

Answer for .Net Core: Return IActionResult as documented here. For example:

        public IActionResult Get(int id = 0)
        {
            try
            {
                var obj = _myRepo.Get(id);                
            }
            catch (Exception ex)
            {
                return BadRequest(ex.Message);
            }

            return Ok(obj);
        }
Rachel
  • 686
  • 1
  • 6
  • 18