14

Asp.Net Web Api のリリース バージョンを使用して API を作成しています。結果が見つからない場合は、正しい応答コード (404) を返そうとしています。

最初のバージョンの取得 (複数の列挙エラーがスローされます):

public IEnumerable<MyObjectType> Get(int id, string format)
{
    var db = new DbEntities();

    var result = db.pr_ApiSelectMyObjectType(store, id, format).AsEnumerable();
    if (result.Any())
    {
        return result;
    }
    var response = new HttpResponseMessage(HttpStatusCode.NotFound) 
        { Content = new StringContent("Unable to find any results") };
    throw new HttpResponseException(response);
}

2 番目のバージョンの取得 (結果が null になることはないため、常に 200 を返します):

public IEnumerable<MyObject> Get(int id, string format)
{
    var db = new DbEntities();

    var result = db.pr_ApiSelectMyObjectType(store, id, format);
    if (result == null)
    {
        var response = new HttpResponseMessage(HttpStatusCode.NoContent) 
            { Content = new StringContent("Unable to find any results") };
        throw new HttpResponseException(response);
    }
    return result.AsEnumerable();
}

結果が見つからない場合、どうすれば 404 を返すことができますか? リストを使用できることはわかっていますが、IEnumerable 型でのみ機能するカスタムの csv メディア タイプ フォーマッタがあるので、それを使い続けることをお勧めします。

4

3 に答える 3

30

より良いアプローチは、アクション フィルター レベルnullでキャッチし、グローバル スコープでアクション フィルターを定義し、これから例外 404 をスローすることです。

public class NullFilter : ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        var response = actionExecutedContext.Response;

        object responseValue;
        bool hasContent = response.TryGetContentValue(out responseValue);

        if (!hasContent)
            throw new HttpResponseException(HttpStatusCode.NotFound);
    }
}

この方法ではAny、アクションで使用する必要はありません。コードはより簡単になります。

public IEnumerable<MyObjectType> Get(int id, string format)
{
    using (db = new DbEntities())
    {
       return db.pr_ApiSelectMyObjectType(store, id, format)
                .AsEnumerable();
    }
}
于 2012-10-02T17:42:46.360 に答える
5

結果をリストに変換するのがおそらく最も簡単です。これは明らかに複数回列挙できます。

var result = db.pr_ApiSelectMyObjectType(store, id, format).ToList();
if (!result.Any())
{
    ...
}

もちろん、それはクエリ全体を具体化することを意味します...しかし、おそらく、とにかくある時点でそれを行うことになるでしょう。

于 2012-10-02T16:55:25.700 に答える