Chase Florell Chase Florell - 1 month ago 34
C# Question

WebAPI CreateResponse with object as generic

I'm trying to figure out a way to return an object in my response while still maintaining an understandable return type.

So for starters, I know this works as expected.

public async Task<HttpResponseMessage> DoMyThing(MyObject myObject)
{
var result = await _myService.CreateMyThingAsync(myObject);
return Request.CreateResponse(HttpStatusCode.Created, result);

}


But what I really want is for this pseudo code to work... somehow.

public Task<MyObject> DoMyThing(MyObject myObject)
{
var result = _myService.CreateMyThingAsync(myObject);
return Request.CreateResponse<Task<MyObject>>(HttpStatusCode.Created, result);
// or better yet
return Request.CreateResponse<MyObject>(HttpStatusCode.Created, result);
}


Is there any magic in the framework that'll make this happen? Or are there any third party libraries that can do this?

Essentially I need to return the
Task<MyObject>
instead of the
Task<HttpResponseMessage>


I'm also open to other suggestions on how to return a non 200 response while still returning the
Task<MyObject>

Answer

The issue with specifying the type as the return type is that you restrict yourself to having to return that type. That may sound strange but actually there will be many cases where you need to be able to support multiple response, such as 404, 200 201 and so on.

To handle the documentation of this you can use the ResponseType attribute, like so:

[ResponseType(typeof(BookDto))]
        public async Task<IHttpActionResult> GetBook(int id)
        {
            BookDto book = await db.Books.Include(b => b.Author)
                .Where(b => b.BookId == id)
                .Select(AsBookDto)
                .FirstOrDefaultAsync();
            if (book == null)
            {
                return NotFound();
            }

            return Ok(book);
        }

Take a look here

Edit:

In Asp.Net Core you use the ProducesResponseType attribute which can be used multiple times per method

See here

Example

[ProducesResponseType(typeof(BookDto), 200)]
[ProducesResponseType(typeof(object), 201)]
         public async Task<IActionResult> GetBook(int id)
            {
                BookDto book = await db.Books.Include(b => b.Author)
                    .Where(b => b.BookId == id)
                    .Select(AsBookDto)
                    .FirstOrDefaultAsync();
                if (book == null)
                {
                    return NotFound();
                }

                return Ok(book);
            }

EDIT: Multiple response attributes prior to dot net core

You can use Swagger to help document / describe your API, they have a custom attribute called SwaggerResponse

The .Net port of Swagger is Swashbuckle, take a look here

Comments