ozb*_*zba 213 c# httpresponse http-status-codes asp.net-web-api
我正在尝试在web api控制器中返回未针对GET方法修改的304的状态代码.
我成功的唯一方法是这样的:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
这里的问题是它不是一个例外,它只是没有修改,所以客户端缓存是好的.我还希望返回类型是User(因为所有web api示例都显示为GET)不返回HttpResponseMessage或类似的东西.
Ali*_*tad 243
我不知道答案,所以在这里问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);
}
Run Code Online (Sandbox Code Playgroud)
小智 68
如果要将操作签名保留为返回用户,也可以执行以下操作:
public User GetUser(int userId, DateTime lastModifiedAtClient)
Run Code Online (Sandbox Code Playgroud)
如果您想要返回除此之外的其他内容,200
您可以HttpResponseException
在您的操作中投入并传入HttpResponseMessage
您想要发送给客户端的内容.
Luk*_*ett 39
更改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);
}
}
Run Code Online (Sandbox Code Playgroud)
*ClientHasStale数据是我检查ETag和IfModifiedSince标头的扩展.
MVC框架仍应序列化并返回您的对象.
注意
我认为在未来的Web API版本中将删除通用版本.
Jon*_*tes 38
在MVC 5中,事情变得更容易:
return new StatusCodeResult(HttpStatusCode.NotModified, this);
Run Code Online (Sandbox Code Playgroud)
dat*_*ung 15
对于 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);
}
Run Code Online (Sandbox Code Playgroud)
Ken*_*rza 13
我讨厌碰到旧文章,但这是谷歌搜索中的第一个结果,我对这个问题有一点时间(即使有你们的支持).所以没有什么......
希望我的解决方案能够帮助那些也很困惑的人.
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后只从BaseController继承
[RoutePrefix("api/devicemanagement")]
public class DeviceManagementController : BaseController
{...
Run Code Online (Sandbox Code Playgroud)
然后使用它
[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);
}
Run Code Online (Sandbox Code Playgroud)
尝试这个 :
return new ContentResult() {
StatusCode = 404,
Content = "Not found"
};
Run Code Online (Sandbox Code Playgroud)
.net core 2.2 returning 304 status code. This is using an ApiController.
[HttpGet]
public ActionResult<YOUROBJECT> Get()
{
return StatusCode(304);
}
Run Code Online (Sandbox Code Playgroud)
Optionally you can return an object with the response
[HttpGet]
public ActionResult<YOUROBJECT> Get()
{
return StatusCode(304, YOUROBJECT);
}
Run Code Online (Sandbox Code Playgroud)
我不喜欢必须更改签名才能使用 HttpCreateResponse 类型,因此我想出了一些扩展解决方案来隐藏它。
public class HttpActionResult : IHttpActionResult
{
public HttpActionResult(HttpRequestMessage request) : this(request, HttpStatusCode.OK)
{
}
public HttpActionResult(HttpRequestMessage request, HttpStatusCode code) : this(request, code, null)
{
}
public HttpActionResult(HttpRequestMessage request, HttpStatusCode code, object result)
{
Request = request;
Code = code;
Result = result;
}
public HttpRequestMessage Request { get; }
public HttpStatusCode Code { get; }
public object Result { get; }
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
return Task.FromResult(Request.CreateResponse(Code, Result));
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以向 ApiController(或者更好的是您的基本控制器)添加一个方法,如下所示:
protected IHttpActionResult CustomResult(HttpStatusCode code, object data)
{
// Request here is the property on the controller.
return new HttpActionResult(Request, code, data);
}
Run Code Online (Sandbox Code Playgroud)
然后你可以像任何内置方法一样返回它:
[HttpPost]
public IHttpActionResult Post(Model model)
{
return model.Id == 1 ?
Ok() :
CustomResult(HttpStatusCode.NotAcceptable, new {
data = model,
error = "The ID needs to be 1."
});
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
254899 次 |
最近记录: |