InvalidCastException' HttpResponseMessage'到了IHttpActionResult'在WebApi2 GET上

时间:2014-08-04 09:54:34

标签: asp.net vb.net asp.net-web-api2

最近,我一直在关注一些WebApi2教程。我有一种情况,如果请求的GET操作返回用户的汇款之外的数据,那么我需要返回一个Forbidden代码。

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

不幸的是,尽管Ok(r)部分正常,CreateErrorResponse会引发InvalidCastException

  

无法转换类型为#System; Net.Net.Http.HttpResponseMessage&#39;的对象输入&#39; System.Web.Http.IHttpActionResult&#39;。

我知道错误发生的原因,但我不确定如何修复它的正确方法。 在其他主题中,人们建议CreateErrorResponse()是WebApi2的最佳方法,但VS会创建它的样本GET请求返回IHttpActionResult。对于我们新手而言,它似乎并不适合我们......

4 个答案:

答案 0 :(得分:5)

不,它不是很明显,但你可以得到你想要的东西(错误代码和消息)并从IHttpActionResult类型的方法返回它。无需更改返回类型或没有错误消息。

这是助手类:

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));
        }
    }

你可以这样称呼它:

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");
}

答案 1 :(得分:2)

试试这个

Get方法更改为返回"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

检查以下链接

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

答案 2 :(得分:0)

我找到了另一种可能的解决方案(可能会有更好的解决方案,但这个解决方案很简单)。它返回

  

403 Forbidden

但没有内容:

<Route("Records/{id}")>
Public Function [Get](id As Int32) As IHttpActionResult
    If Not Remit.IsWithinRemit(id) Then
        Return New Results.StatusCodeResult(HttpStatusCode.Forbidden, Request)
    Else
        Dim r As New CustomObject(id)
        Return Ok(r)
    End If
End Function

由于HttpResponseMessage来自same namespace,并且除了HTTP status code之外还允许您返回自定义错误消息,因此该选项更适合在大多数情况下使用。

我猜IHttpActionResult是基本状态代码返回而没有多余的装饰。我将此与上述答案一起发布,以便让新编码人员了解这两个选项。

答案 3 :(得分:0)

我在使用.NET Framework 4.7.2时遇到了相同的错误。我没有从IHttpActionResult更改返回类型**,而是通过将HttpResponseMessage对象包装在ResponseMessageResult中来纠正了该错误,如下所示:-

return new ResponseMessageResult(myHttpResponseMessage);

**这是case块中一组简单的IHttpActionResult案例中的一个单一的自定义switch