C# Asp.Net Web Api-返回IEnumerable的404<;T>;空时获取

C# Asp.Net Web Api-返回IEnumerable的404<;T>;空时获取,c#,asp.net,asp.net-web-api,C#,Asp.net,Asp.net Web Api,我正在使用Asp.NETWebAPI的发行版创建一个API。如果没有找到结果,我将尝试传回正确的响应代码(404) 第一个获取版本(引发多个枚举错误): public IEnumerable<MyObjectType> Get(int id, string format) { var db = new DbEntities(); var result = db.pr_ApiSelectMyObjectType(store, id, format).AsEnumera

我正在使用Asp.NETWebAPI的发行版创建一个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);
}
公共IEnumerable Get(int-id,字符串格式) { var db=新的DbEntities(); var result=db.pr_ApiSelectMyObjectType(存储、id、格式).AsEnumerable(); if(result.Any()) { 返回结果; } var响应=新的HttpResponseMessage(HttpStatusCode.NotFound) {Content=new StringContent(“找不到任何结果”)}; 抛出新的HttpResponseException(响应); } Second-Get-Version(结果从不为空,因此它总是返回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();
}
公共IEnumerable Get(int-id,字符串格式) { var db=新的DbEntities(); var result=db.pr\u APISelectMyObject类型(存储、id、格式); 如果(结果==null) { var响应=新的HttpResponseMessage(HttpStatusCode.NoContent) {Content=new StringContent(“找不到任何结果”)}; 抛出新的HttpResponseException(响应); } 返回结果; }
如果找不到结果,如何传回404?我知道我可以使用列表,但我有一个自定义的csv媒体类型格式化程序,它只适用于IEnumerable类型,所以我更愿意使用它

将结果转换成一个列表可能是最简单的,显然可以多次枚举:

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

当然,这意味着实现整个查询。。。但想必您最终还是会在某个时候这样做。

更好的方法是在操作筛选器级别捕获
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);
    }
}
通过这种方式,您不需要在操作中使用
任何
,代码会更简单:

public IEnumerable<MyObjectType> Get(int id, string format)
{
    using (db = new DbEntities())
    {
       return db.pr_ApiSelectMyObjectType(store, id, format)
                .AsEnumerable();
    }
}
公共IEnumerable Get(int-id,字符串格式) { 使用(db=new DbEntities()) { 返回db.pr\u APISelectMyObject类型(存储、id、格式) .AsEnumerable(); } }
在您的情况下,不要返回:

return result.AsEnumerable();
您可以返回空值:

return null;
在调用函数中,检查返回的结果,如下所示:

var myObject = Get(id, format);
if (myObject == null)
    return NotFound(myObject);
else
    return Ok(myObject);

如果get函数找不到记录,那么这样做将得到404 not found。

1。我相信使用
result.Count!=0
应该更快,因为它不会使用
可枚举的
扩展方法,该扩展方法创建迭代器块而不是列表的属性。2.使用web API v2和OData,您可能希望返回IQueryable和not List(或IEnumerable)。@gdoron:我相信
Any()
无论如何都是针对
ICollection
实现进行优化的,但在过滤序列的情况下,它可能比使用
Count()
更有效。