Web API的“Request”为空。

5
我正在尝试使用“Request”从一个POST Web API操作返回一个HttpResponseException
throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.NotFound, "File not in a correct size"));

这样做时,我得到了“值不能为 null。参数名: request”。

本质上 - 请求是 null。

我错过了什么?

谢谢


要确认,请尝试使用 throw new HttpResponseException(HttpStatusCode.NotFound) - Rwiti
嗨Rwiti,你的建议确实有效,如下所示:throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.InternalServerError) { Content = new StringContent("Invalid size"), StatusCode = HttpStatusCode.Forbidden });但是在客户端(JS)上,我无法获取“Content”属性。有什么想法吗? - Leo
7个回答

6

我发现在我的ApiController中,我的Request对象为null,因为我在其中嵌套了一个ApiController调用。第二个嵌套的ApiController从未被初始化。你不能手动初始化它,但是你可以利用Request对象上的setter方法将其从包装器传递到嵌套的ApiController中。下面是一个示例,在我的实际代码中,它修复了我的Request.CreateErrorResponse(...)错误。

public class WrapperController : ApiController
{
    // POST api/wrapper
    public void Post(ComplexWithChild value)
    {
        var other = value.otherdata;

        var childcontroller = new ChildController();
        childcontroller.Post(value.child); // ChildController is not initialized, and has null Request
        /*inside ChildController...// causes null reference exception due to null Request
            Request.CreateErrorResponse(HttpStatusCode.BadRequest, "my message"); 
        */

        childcontroller.Request = this.Request;
        childcontroller.Post(value.child); // ChildController uses same Request
        /*inside ChildController...// this works now
            Request.CreateErrorResponse(HttpStatusCode.BadRequest, "my message"); 
        */
    }
}

public class ChildController : ApiController
{
    public void Post(Child value)
    {
        throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, "my message"));
    }
}

1
这段代码可能只适用于Web Api 1,我认为它在Asp.Net Web Api 2中不起作用。 - DavB.cs
我收到了System.InvalidOperationException: 'The request context property on the request must be null or match ApiController.RequestContext.'的错误信息。 - Jesus is Lord

2

对于像 @DavB.cs 这样具有嵌套 ApiControllers(如下所示)的人,另一种解决方案是:

public class ParentController : ApiController
{
    public IHttpActionResult Foo()
    {
       ChildRepository.Foo();
       return Ok(...);
    }
}

public class ChildRepository : ApiController
{
    public HttpResponseMessage Foo()
    {
        // Do something
        return Request.CreateResponse(...);
    }
}

只需从ParentController传入Request即可,如下所示:
public class ParentController : ApiController
    {
        public IHttpActionResult Foo()
        {
           ChildRepository.Foo(Request);
           return Ok(...);
        }
    }

    public class ChildRepository
    {
        public HttpResponseMessage Foo(HttpRequestMessage request)
        {
            // Do something
            return request.CreateResponse(...);
        }
    }

请求来自ApiController。这将帮助您解决“请求为空”的问题。

希望对某些人有所帮助。


1
在所有建议的解决方案中(我也使用过),这是我最喜欢的,谢谢Aaron。 - DavB.cs

2
请使用以下内容:
HttpResponseMessage message = new HttpResponseMessage(HttpStatusCode.InternalServerError);
message.Content = new ObjectContent(typeof(MessageResponse), "Invalid Size", GlobalConfiguration.Configuration.Formatters.JsonFormatter);
throw new HttpResponseException(message);

注意:您可以将“无效大小”更改为任何您想要返回给用户的对象。 例如:
public ErrorMessage
{
     public string Error;
     public int ErrorCode;
}

ErrorMessage msg = new ErrorMessage();
msg.Error = "Invalid Size";
msg.ErrorCode = 500;

HttpResponseMessage message = new HttpResponseMessage(HttpStatusCode.InternalServerError);
message.Content = new ObjectContent(typeof(MessageResponse), msg, GlobalConfiguration.Configuration.Formatters.JsonFormatter);
throw new HttpResponseException(message);

2
谢谢,这是正确的并且可以工作,但我仍然想知道为什么在那种情况下 'Request' 是 null。 - Leo
@Leo,你找到了Web API控制器中Request为空的原因吗? - Toolkit

0

在nizari的回答基础上,这是我为了包含ErrorMessage对象列表所做的操作:

IEnumerable errorList = new List<ErrorMessage>();

// ...

var error = new HttpError( "There were errors." ) 
{
    { "Errors", errorList }
};

var message = new HttpResponseMessage( HttpStatusCode.BadRequest )
{
    Content = new ObjectContent<HttpError>( error, GlobalConfiguration.Configuration.Formatters.JsonFormatter )
};

throw new HttpResponseException( message );

0

nizari的答案是正确的,但我最终使用了以下内容:

throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.InternalServerError)
                    {
                        Content = new StringContent("Invalid image dimensions. Image file must be " + image.Width + "x" + image.Height + "px"),
                        StatusCode = HttpStatusCode.Forbidden
                    });

通过jqXHR.responseText在客户端访问内容

谢谢大家!


0

您需要创建一个新的 System.Net.Http.HttpRequestMessage 实例。以下代码可以实现:

var request = new HttpRequestMessage();
var response = request.CreateErrorResponse(HttpStatusCode.NotFound, "文件大小不正确");
throw new HttpResponseException(response);

-1
HttpResponseMessage message = new  HttpResponseMessage(HttpStatusCode.InternalServerError); 
message.Content = new ObjectContent(typeof(MessageResponse),
                                    "Invalid Size",
                                    GlobalConfiguration.Configuration.Formatters.JsonFormatter); 
throw new HttpResponseException(message);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接