Return a list of error messages with 400 Bad Request response in Web API 2 - asp.net-web-api

How can I return a list of error messages from Web Api 2 with 400 Bad Request status code? See the example below. Usually I use BadRequest method to return the 400 status code but it doesn't have any overload where it accepts a collection of string. It has an overload where it accepts ModelStateDisctionary. Does it mean I will have to create ModelStateDictionary from a list of error messages?
[Route("")]
[HttpPost]
public IHttpActionResult Add(Object data)
{
var valid = _serviceLayer.Validate(data);
if(!valid)
{
var errors = valid.Errors;
// errors is an array of string
// How do I return errors with Bad Request status code here?
}
var updatedObject = _serviceLayer.Save(data);
return Ok(updatedObject);
}

As per Mike's comment, I am going to add a new class implementing IHttpActionResult to return a list of error messages with 400 Bad Request. Thanks Mark

Related

SpringBoot WebClient - exchangeToMono

I need to make a external API call from my Spring service. I am planning to return a Response object,
containing status code, actual json response. So that, the caller can decide how to decode the json based on the status code. Example - If status is 2xx - save the response, 4xx - log it in some error table etc.
I have done something like this. But, I am not sure whether the approach is correct or not.
Basically, I need to return the json and the status code for all status codes.
Wondering, how to achieve this with exchangeToMono.
The below code snippet works fine but I am not sure it's correct or not.
Appreciate any help or suggestions...
ResponseObj has two properties - statusCode and json.
public ResponseObj getExternalData() {
ResponseObj obj = new ResponseObj();
Mono<String> result = webclient.get().
.uri("/some/external/api")
.headers( //headers)
.exchangeToMono( response -> {
obj.setStatusCode(response.rawStatusCode());
return response.bodyToMono(String.class);
});
obj.setJson(result.block));
return obj;
}

SOAP UI response

I want to view the response for the below method in SOAP UI. The url would be as below to call the accountDetails(..) method in SOAP UI to check the response.
http://localhost:8080/AccountInfo/rest/account/0003942390
#RequestMapping(value = /accountDetails/{accNum}, method = RequestMethod.GET)
public void accountDetails(#PathVariable final String accNum)
{
final boolean accountValue = service.isAccountExists(accNum);
if (!accountValue )
{
throw new Exception();
}
}
The method is executed correctly but the response i'm getting in SOAP UI is 404.
accountDetails(..) method return type is void, so do i need to set any extra parameters when i have to check the response for the method in SOAP UI with void return type to show success message.
Below is the message shown in SOAP UI:
HTTP/1.1 404 /AccountInfo/WEB-INF/jsp/account/0003942390/accountInfo.jsp
Server: Apache-Coyote/1.1
Is the exception thrown? If yes, how does the framework handle the exception?
Your method doesn't return anything - see here. Based on the RESTful nature of the URL it seems the method should return something like an AccountDetail. However, if you really just want to see the 200 then just return something like a non-null String.

Internal Server Error (500) when creating a document in DocumentDB from data passed on from Console Application to ASP.NET WebAPI

I have an ASP.NET WebAPI Controller which creates a document in Azure DocumentDB from the data passed on to its POST method from a Console app. The return type of the POST method is HttpResponseMessage which returns a status code for OK (i.e. 200) when the document has been successfully created.
The document gets created successfully from the WebAPI and the status code 200 is returned too. But somewhere then it goes wrong (which I can't figure out where and why) and the status code that my Console app receives after the successful POST is 500 - an Internal Server Error occurred.
public HttpResponseMessage Post([FromBody]GPSDataVM data)
{
if (KeyRepository.IsValid(data.Key))
{
// Creates a document in DocumentDB by calling an async method CreateLiveDataDocument(data);
return new HttpResponseMessage(HttpStatusCode.OK);
}
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
}
Can anyone help me out with the situation? Thanks in advance ..
I found an answer to my problem from the following address:
Web Api + HttpClient: An asynchronous module or handler completed while an asynchronous operation was still pending
I changed the definition to my WebAPI Controller to:
public **async Task<HttpResponseMessage>** Post([FromBody]GPSDataVM data) {
if (KeyRepository.IsValid(data.Key))
{
// Creates a document in DocumentDB by calling an async method
**// Code for CreateLiveDataDocument(data)**
return new HttpResponseMessage(HttpStatusCode.OK);
}
return new HttpResponseMessage(HttpStatusCode.Unauthorized); }

Empty request body gives 400 error

My Spring controller method looks something like this:
#RequestMapping(method=RequestMethod.PUT, value="/items/{itemname}")
public ResponseEntity<?> updateItem(#PathVariable String itemname, #RequestBody byte[] data) {
// code that saves item
}
This works fine except when a try to put a zero-length item, then I get an HTTP error: 400 Bad Request. In this case my method is never invoked. I was expecting that the method should be invoked with the "data" parameter set to a zero-length array.
Can I make request mapping work even when Content-Length is 0?
I am using Spring framework version 4.1.5.RELEASE.
Setting a new byte[0] will not send any content on the request body. If you set spring MVC logs to TRACE you should see a message saying Required request body content is missing as a root cause of your 400 Bad Request
To support your case you should make your #RequestBody optional
#RequestMapping(method=RequestMethod.PUT, value="/items/{itemname}")
public ResponseEntity<?> updateItem(#PathVariable String itemname, #RequestBody(required = false) byte[] data) {
// code that saves item
}

How to change the response code when not using HttpResponseMessage?

I have this example of ASP.NET Web Api controller:
public Mea Get(Int32 id)
{
try
{
return Meas.GetById(id) ?? new Mea(-1, 0D, 0D);
}
catch (Exception)
{
return new Mea(-1, 0D, 0D);
}
}
I want to be able to return a different response code if the GetById returns null or in the catch exception.
All the examples that I see use HttpResponseMessage where you can add the response code.
My question is how to change the response code when not using HttpResponseMessage, like in the above example?
Well if you want to have different response code to be return from your function then you will have to wrap it in in a HttpResponseMessage.
Your function will always return an status code "200". Even if you return a bare object the framework pipeline will convert it to a HttpResponseMessage with default status code HttpStatusCode.OK, so better you do it by yourself.
What I would suggest is do not return bare objects/values from your API function. Always wrap the values in a HttpResponseMessage and then return a response message from your function.Basically by wrapping it in the HttpResponseMessage you can have proper status code in client side. Returning HttpResponseMessage is always the best practice.
So please change your function like this
public HttpResponseMessage Get(Int32 id)
{
try
{
// on successful execution
return this.Request.CreateResponse(HttpStatusCode.OK, Meas.GetById(id) ?? new Mea(-1, 0D, 0D));
}
catch (Exception)
{
return this.Request.CreateResponse(HttpStatusCode.InternalServerError, Mea(-1, 0D, 0D));
}
}
in the case of an error you can also throw an HttpResponseException
You can throw a System.Web.Http.HttpResponseException, specifying an HTTP status code and/or optionally a whole HttpResponseMessage to be returned to the client.

Resources