提问者:小点点

从Web Api控制器返回http状态代码


我试图为web api控制器中的GET方法返回一个状态代码304 not modified。

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

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

这里的问题是,它并不是一个例外,它只是没有被修改,所以客户端缓存是可以的。我还希望返回类型为User(正如所有web api示例使用GET显示的那样),而不是返回HttpResponseMessage或类似的内容。


共3个答案

匿名用户

我不知道答案,所以问这里的ASP.NET团队。

所以诀窍是将签名更改为,并使用

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

匿名用户

如果希望将操作签名保留为返回用户,还可以执行以下操作:

public User GetUser(int userId, DateTime lastModifiedAtClient) 

如果您想返回以外的内容,那么您可以在操作中抛出一个,并将想要发送到客户端的传入。

匿名用户

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

*ClientHastale data是我检查ETag和IfModifiedSince头的扩展。

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

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