245

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

ここでの問題は、例外ではないということです。変更されていないだけなので、クライアント キャッシュは問題ありません。また、戻り値の型を User にしたい (すべての Web API の例が GET で示しているように) HttpResponseMessage などを返さないでください。

4

14 に答える 14

271

答えがわからなかったので、ここで 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);
}
于 2012-05-18T19:25:14.750 に答える
68

アクション署名をユーザーを返すものとして保持する場合は、次のこともできます。

public User GetUser(int userId, DateTime lastModifiedAtClient) 

それ以外のものを返したい場合は、アクションで200をスローし、クライアントに送信したい を渡します。HttpResponseExceptionHttpResponseMessage

于 2012-06-15T20:41:04.023 に答える
42

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フレームワークは、オブジェクトをシリアル化して返す必要があります。

ノート

汎用バージョンは、WebAPIの将来のバージョンで削除されると思います。

于 2012-07-04T11:31:51.810 に答える
41

MVC 5 では、次のように簡単になりました。

return new StatusCodeResult(HttpStatusCode.NotModified, this);
于 2015-04-01T10:57:31.893 に答える
4

別のオプション:

return new NotModified();

public class NotModified : IHttpActionResult
{
    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        var response = new HttpResponseMessage(HttpStatusCode.NotModified);
        return Task.FromResult(response);
    }
}
于 2016-11-15T13:56:13.013 に答える
3

IHttpActionResult を返す必要があり、エラー コードとメッセージを返したい場合は、次を使用します。

return ResponseMessage(Request.CreateErrorResponse(HttpStatusCode.NotModified, "Error message here"));
于 2016-07-29T05:55:11.307 に答える
0

ここにはいくつかの良い答えがあることは知っていますが、これは私が必要としていたものなので、他の誰かが webAPI を使用して 4.7.x で必要なステータス コードと応答本文を返す必要がある場合に備えて、このコードを追加すると考えました。

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));
    }
}
于 2021-01-04T21:14:22.010 に答える