我试图返回一个状态代码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或类似的东西。
使用Web API 2中引入的更现代的IHttpActionResult对@Aliostads进行了更新。
https://learn.microsoft.com/en-us/aspnet/web-api/overview/getting-started-with-aspnet-web-api/action-results#ihttpactionresult
public class TryController : ApiController
{
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);
// If you would like to return a Http Status code with any object instead:
// return Content(HttpStatusCode.InternalServerError, "My Message");
}
return Ok(user);
}
}
我讨厌撞旧文章,但这是在谷歌搜索的第一个结果,我有一个问题(即使有你们的支持)。所以这里什么都没有……
希望我的解决方案能帮助那些同样感到困惑的人。
namespace MyApplication.WebAPI.Controllers
{
public class BaseController : ApiController
{
public T SendResponse<T>(T response, HttpStatusCode statusCode = HttpStatusCode.OK)
{
if (statusCode != HttpStatusCode.OK)
{
// leave it up to microsoft to make this way more complicated than it needs to be
// seriously i used to be able to just set the status and leave it at that but nooo... now
// i need to throw an exception
var badResponse =
new HttpResponseMessage(statusCode)
{
Content = new StringContent(JsonConvert.SerializeObject(response), Encoding.UTF8, "application/json")
};
throw new HttpResponseException(badResponse);
}
return response;
}
}
}
然后从BaseController继承
[RoutePrefix("api/devicemanagement")]
public class DeviceManagementController : BaseController
{...
然后使用它
[HttpGet]
[Route("device/search/{property}/{value}")]
public SearchForDeviceResponse SearchForDevice(string property, string value)
{
//todo: limit search property here?
var response = new SearchForDeviceResponse();
var results = _deviceManagementBusiness.SearchForDevices(property, value);
response.Success = true;
response.Data = results;
var statusCode = results == null || !results.Any() ? HttpStatusCode.NoContent : HttpStatusCode.OK;
return SendResponse(response, statusCode);
}
更改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版本中被删除。