2012-10-02 46 views
8

我使用Asp.Net Web Api的發行版本創建API。如果沒有找到結果,我試圖傳回正確的響應代碼(404)。Asp.Net Web Api - 爲IEnumerable返回404 <T> Get null

首先得到版本(拋出多個枚舉錯誤):

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

二獲取版本(結果絕不會是零,所以它總是返回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。我知道我可以使用一個列表,但我有一個自定義的csv媒體類型格式化程序,它只適用於IEnumerable類型,所以我寧願堅持。

回答

4

這是最簡單的,只是結果轉換到一個列表,這顯然可以列舉多次大概:

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

當然,這意味着物化整個查詢...但想必你最終做無論如何,在某個時刻。

+0

1.我相信使用'result.Count = 0'應該會更快,因爲它不會使用'Enumerable'的'Any'擴展方法哪!創建一個迭代器塊但是一個li st的財產。 2.使用Web API v2和OData,您可能希望返回IQueryable而不是List(或IEnumerable)。 – gdoron

+2

@gdoron:我相信'Any()'是針對'ICollection '實現進行了優化的,但是如果它是一個被過濾的序列,它可能比使用Count()更有效率。 –

25

更好的方法是在行爲過濾級別趕上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(); 
    } 
}