我试图返回一个状态代码304未修改的web api控制器中的GET方法。

我成功的唯一方法是这样的:

public class TryController : ApiController
{
    public User GetUser(int userId, DateTime lastModifiedAtClient)
    {
        var user = new DataEntities().Users.First(p => p.Id == userId);
        if (user.LastModified <= lastModifiedAtClient)
        {
             throw new HttpResponseException(HttpStatusCode.NotModified);
        }
        return user;
    }
}

这里的问题是,它不是一个异常,它只是没有修改,所以客户端缓存是OK的。 我还希望返回类型是一个用户(所有的web api示例显示与GET)不返回HttpResponseMessage或类似的东西。


当前回答

我知道这里有几个很好的答案,但这是我需要的,所以我想我应该添加这个代码,以防任何人需要返回任何状态代码和响应体,他们想在4.7。x与webAPI。

public class DuplicateResponseResult<TResponse> : IHttpActionResult
{
    private TResponse _response;
    private HttpStatusCode _statusCode;
    private HttpRequestMessage _httpRequestMessage;
    public DuplicateResponseResult(HttpRequestMessage httpRequestMessage, TResponse response, HttpStatusCode statusCode)
    {
        _httpRequestMessage = httpRequestMessage;
        _response = response;
        _statusCode = statusCode;
    }

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        var response = new HttpResponseMessage(_statusCode);
        return Task.FromResult(_httpRequestMessage.CreateResponse(_statusCode, _response));
    }
}

其他回答

在MVC 5中,事情变得更简单了:

return new StatusCodeResult(HttpStatusCode.NotModified, this);

更改GetXxx API方法以返回HttpResponseMessage,然后返回完整响应的类型化版本和NotModified响应的非类型化版本。

    public HttpResponseMessage GetComputingDevice(string id)
    {
        ComputingDevice computingDevice =
            _db.Devices.OfType<ComputingDevice>()
                .SingleOrDefault(c => c.AssetId == id);

        if (computingDevice == null)
        {
            return this.Request.CreateResponse(HttpStatusCode.NotFound);
        }

        if (this.Request.ClientHasStaleData(computingDevice.ModifiedDate))
        {
            return this.Request.CreateResponse<ComputingDevice>(
                HttpStatusCode.OK, computingDevice);
        }
        else
        {
            return this.Request.CreateResponse(HttpStatusCode.NotModified);
        }
    }

* ClientHasStale数据是我的扩展检查ETag和IfModifiedSince头。

MVC框架仍然应该序列化并返回您的对象。

NOTE

我认为通用版本将在未来的Web API版本中被删除。

ASP。NET Web Api 2,这篇文章从MS建议改变方法的返回类型IHttpActionResult。然后,您可以返回一个内置的IHttpActionResult实现,如Ok, BadRequest等(参见这里)或返回您自己的实现。

对于你的代码,可以这样做:

public IHttpActionResult GetUser(int userId, DateTime lastModifiedAtClient)
{
    var user = new DataEntities().Users.First(p => p.Id == userId);
    if (user.LastModified <= lastModifiedAtClient)
    {
        return StatusCode(HttpStatusCode.NotModified);
    }
    return Ok(user);
}

我不知道答案所以问ASP。NET团队。

因此,诀窍是将签名更改为HttpResponseMessage并使用Request.CreateResponse。

[ResponseType(typeof(User))]
public HttpResponseMessage GetUser(HttpRequestMessage request, int userId, DateTime lastModifiedAtClient)
{
    var user = new DataEntities().Users.First(p => p.Id == userId);
    if (user.LastModified <= lastModifiedAtClient)
    {
         return new HttpResponseMessage(HttpStatusCode.NotModified);
    }
    return request.CreateResponse(HttpStatusCode.OK, user);
}

试试这个:

return new ContentResult() { 
    StatusCode = 404, 
    Content = "Not found" 
};