从服务访问HttpContext的正确方法

时间:2016-05-17 22:03:55

标签: c# asp.net-web-api

我创建了一项服务,允许我访问controllername,actionname&来自HttpContext.Current

的标头值

目前我正在尝试测试服务并在服务中发现使用HttpContext可能是一个坏主意,因为我的服务层需要完全了解HttpContext

e.g。

    public virtual string GetControllerName()
    {
        return HttpContext.Current.Request.RequestContext.RouteData.Values["controller"].ToString();
    }

然后我考虑将请求作为一个参数传递,但是再次感觉不对。

   public virtual string GetActionName(HttpRequest request)
   {
      return request.RequestContext.RouteData.Values["action"].ToString();
   }

任何人都可以提供和指导如何设置我的服务以使我能够达到我的需要吗?

1 个答案:

答案 0 :(得分:1)

如果您的服务类“意识到”存在控制器和操作,则它知道在向控制器发出HTTP请求期间调用它。如果是这种情况,则它不会与控制器分离 - 换句话说,如果在服务请求时没有调用该服务,则该服务无法运行。因为如果是,就没有控制器或动作。

因此,从这个角度来看,服务直接依赖于HttpContext并不重要,因为无论哪种方式都与它相关联。

服务类是否确实需要这些特定的值,或者它只是执行一些日志记录而你想知道它叫什么?

如果它取决于那些值,那么你可以创建一个像

这样的界面
interface IControllerContextProvider
{
    string ControllerName;
    string ActionName;
}

然后有一个类似

的实现
public class HttpContextControllerContextProvider : IControllerContextProvider
{
    //implements the interface by returning values from HttpContext.Current
}

如果服务本身不需要这些值来运行(可能只是记录)那么你可以使用一个拦截器(见PostSharpWindsor,其他),当你注入你的时候服务器进入你的控制器,拦截器“拦截”调用,进行记录,然后继续原始方法调用。

拦截器是为特定目的而编写的类,因此将它与您的HttpContext耦合是有意义的。但好处是,如果有关控制器和操作的详细信息与服务类的主要用途无关,那么拦截器提供了一种方法来保持代码不在服务类中。

通过异常日志记录完成了很多工作。如果一个类不会真正处理异常,那么它就不需要包含用于记录错误的代码,因为这不是该类的目的。拦截器让我们创建这些行为,但将它们与不关心它们的类分开。