用于空响应的ASP.NET Web API和状态代码

时间:2012-09-25 23:17:11

标签: asp.net-mvc-4 asp.net-web-api

如果服务层未找到请求的资源,则返回null给Web API控制器;什么是将HttpStatusCode.NotFound响应抛回客户端而不在控制器中对其进行硬编码,以及检查它是否为空的最佳方法?

2 个答案:

答案 0 :(得分:15)

就我个人而言,我会按照Oppositional的评论对控制器进行检查,但你所要求的是完全合理的。再次使用每个控制器附加的动作过滤器(或全局注册),您可以按照以下方式执行操作:

示例模型:

public class Foo
{
    public string Bar { get; set; }
}

示例控制器:

public class FoosController : ApiController
{
    [NullObjectActionFilter]
    public Foo Get(string id)
    {
        // - Returns model and 200
        //return new Foo() { Bar = "TEST" };

        // - Returns 404
        //return null;
    }
}

过滤器:

public class NullObjectActionFilter : ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        object outValue = null;
        actionExecutedContext.Response.TryGetContentValue<object>(out outValue);
        if (outValue == null)
        {
            throw new HttpResponseException(HttpStatusCode.NotFound);
        }

        base.OnActionExecuted(actionExecutedContext);

    }
}

答案 1 :(得分:11)

我同意马克认为ActionFilter是可行的方法 - 小动作方法是一种很好的气味。

但是,发生异常时HttpActionExecutedContext.Response可以是null;并且上面显示的NullObjectActionFilter类可能会掩盖错误的HTTP状态代码。您最好检查成功退出和成功的HTTP代码。

这是我使用的动作过滤器:

/// <summary>
/// Converts <c>null</c> return values into an HTTP 404 return code.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class NullResponseIs404Attribute : ActionFilterAttribute
{

    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        if ((actionExecutedContext.Response != null) && actionExecutedContext.Response.IsSuccessStatusCode)
        {
            object contentValue = null;
            actionExecutedContext.Response.TryGetContentValue<object>(out contentValue);
            if (contentValue == null)
            {
                actionExecutedContext.Response = actionExecutedContext.Request.CreateErrorResponse(HttpStatusCode.NotFound, "Object not found");
            }
        }
    }

}