2012-10-02 7 views
8

Asp.Net Web Api'nin yayın sürümünü kullanarak bir API oluşturuyorum. Hiçbir sonuç bulunamazsa doğru yanıt kodunu (404) geri göndermeye çalışıyorum.Asp.Net Web Api - IEnumerable için 404 Dönen <T> Get Ne zaman

İlk Sürüm alın (atar çoklu numaralandırma hatası):

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

İkinci Sürüm (sonuç boş asla, bu yüzden her zaman 200 döndürür) alın:

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

nasıl Hiçbir sonuç bulunamazsa 404'ü geri veriyorum? Bir listeyi kullanabileceğimi biliyorum, ancak yalnızca IEnumerable tipleriyle çalışan bir özel csv media type formatterim var, bu yüzden bunu yapmayı tercih ederim.

cevap

4

O var muhtemelen sadece besbelli sıralanabilir listesi sonuçları dönüştürmek için en basit birden çok kez:

var result = db.pr_ApiSelectMyObjectType(store, id, format).ToList(); 
if (!result.Any()) 
{ 
    ... 
} 
tüm sorguyu hayata demektir Tabii

... ama muhtemelen yaptığını bitirmek istiyorum Bu zaten bir noktada.

+0

1. kullanıyorum inanıyorum 'result.Count = 0' daha hızlı o' Enumerable' en 'Any' uzatma yöntemini kullanmaz olarak olması gereken! bir yineleme bloğu oluşturur ancak bir li st özelliği. 2. web API v2 ve OData ile muhtemelen IQueryable ve List (veya IEnumerable) değil dönmek isteyeceksiniz. – gdoron

+2

@gdoron: "Any()", "ICollection " uygulamalarının her zaman için optimize edildiğine inanıyorum, ancak potansiyel olarak filtrelenmiş bir dizi olduğu durumlarda Count() 'ı kullanmaktan çok daha verimlidir. –

25

Daha iyi yaklaşım, eylem filtre seviyesinde de null yakalamak küresel kapsamı ile bir eylem filtreyi tanımlamak ve bundan istisna 404 atılmasıdır: Bu yolla

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

, kullanmak gerekmez senin eylem Any, kod daha basit olacaktır:

public IEnumerable<MyObjectType> Get(int id, string format) 
{ 
    using (db = new DbEntities()) 
    { 
     return db.pr_ApiSelectMyObjectType(store, id, format) 
       .AsEnumerable(); 
    } 
}