Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

InvalidCastException 'HttpResponseMessage' to 'IHttpActionResult' on WebApi2 GET

Recently I've been following some WebApi2 tutorials. I have a situation whereby if a requested GET operation returns data outside of the user's remit, then I need to return a Forbidden code.

Imports System.Net
Imports System.Net.Http
Imports System.Web.Http

Namespace Controllers

    Public Class MyController
        Inherits ApiController

        <Route("Records/{id}")>
        Public Function [Get](id As Int32) As IHttpActionResult
            If Not Remit.IsWithinRemit(id) Then
                Return Request.CreateErrorResponse(HttpStatusCode.Forbidden, "This data is not within your remit")
            Else
                Dim r As New CustomObject(id)
                Return Ok(r)
            End If
        End Function

    End Class

End Namespace

Unfortunately, although the Ok(r) part works okay, CreateErrorResponse throws an InvalidCastException:

Unable to cast object of type 'System.Net.Http.HttpResponseMessage' to type 'System.Web.Http.IHttpActionResult'.

I know why the error is happening, but am unsure of the correct approach of how to fix it. In other threads, people advise that CreateErrorResponse() is the best approach for WebApi2, but VS creates it's sample GET request returning IHttpActionResult. Its like stuff doesn't seem to fit together for us newbies at the moment...

like image 378
EvilDr Avatar asked Dec 21 '25 02:12

EvilDr


2 Answers

No, it isn't obvious, but you can get what you want (error code plus message) AND return it from a method of type IHttpActionResult. No need to change the return type or go without error messages.

This is the helper class:

public class ErrorResult : IHttpActionResult
    {
        private HttpRequestMessage Request { get; }
        private HttpStatusCode statusCode;
        private string message;

        public ErrorResult(HttpRequestMessage request, HttpStatusCode statusCode, string message)
        {
            this.Request = request;
            this.statusCode = statusCode;
            this.message = message;
        }

        public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
        {
            return Task.FromResult(Request.CreateErrorResponse(statusCode, message));
        }
    }

and you can call it like this:

public IHttpActionResult MyMethod()
{
    MyServiceLayer myServiceLayer = new MyServiceLayer();
    MyType myvar;
    if (MyServiceLayer.EverythingIsOK(ref myvar))
        return Ok(myvar);
    else 
        return new ErrorResult(Request, HttpStatusCode.SomeErrorCode, "Something Is Wrong");
}
like image 168
toddmo Avatar answered Dec 22 '25 18:12

toddmo


try this

Change your Get method to return "HttpResponseMessage"

<Route("Records/{id}")>
Public Function [Get](id As Int32) As HttpResponseMessage
    If Not Remit.IsWithinRemit(id) Then
        Return Request.CreateResponse(HttpStatusCode.Forbidden, "This data is not within your remit")
    Else
        Dim r As New CustomObject(id)
        Return Request.CreateResponse(HttpStatusCode.OK, r)
    End If
End Function

Check below link

http://www.asp.net/web-api/overview/web-api-routing-and-actions/action-results

like image 40
malkam Avatar answered Dec 22 '25 17:12

malkam



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!