【问题标题】:Use Httpcontext in data Access Layer在数据访问层使用 Httpcontext
【发布时间】:2012-04-15 12:50:33
【问题描述】:

我很想在 dataAceess 层中使用 HttpContext,但我无法从 HttpContext 创建对象

 HttpContext httpContext = HttpContext.Current;

我创建了一个 Web 应用程序和一个 libery 项目,我想在 libery 项目中使用 HttpContext,如下所示:

public static Context GetContextPerRequest()
   {

       HttpContext httpContext = HttpContext.Current;
       if (httpContext == null)
       {
           return new Context();
       }
       else
       {
           int contextId = Thread.CurrentContext.ContextID;
           int hashCode = httpContext.GetHashCode();
           string key = string.Concat(hashCode, contextId);

           Context context = httpContext.Items[key] as Context;
           if (context == null)
           {
               context = new Context();
               httpContext.Items[key] = context;
           }

           return context;
       }
   }

我使用 .net 4。

【问题讨论】:

  • 数据访问层应该依赖于像HttpContext这样的面向UI的组件。这样做会强烈地将您的“数据访问层”与 ASP.NET Web 应用程序联系起来——您将无法将其用于例如WCF 服务或 WPF 应用程序......我认为这是一个非常非常糟糕的设计......
  • 最简单的解决方案是添加对 System.Web 的引用

标签: asp.net entity-framework c#-4.0 entity-framework-4.1


【解决方案1】:

您可以从表示层解析HttpContext.Current 并更改您的方法,如下所示。如果您需要找到一种访问当前 http 上下文的方法,this 链接将为您提供帮助。

   public static Context GetContextPerRequest(HttpContext httpContext)
   {
      ------
      ------
   }

【讨论】:

    【解决方案2】:

    我不确定您的问题是什么,但您的代码显示了一些非常糟糕的概念。

    你认为这会做什么?

    int contextId = Thread.CurrentContext.ContextID;
    int hashCode = httpContext.GetHashCode();
    string key = string.Concat(hashCode, contextId);
    
    Context context = httpContext.Items[key] as Context;
    if (context == null)
    {
        context = new Context();
        httpContext.Items[key] = context;
    }
    

    HttpContext 是您在 ASP.NET 中处理 HTTP 请求的安全存储。 HttpContext.Current 为每个请求返回唯一实例,并且该实例独立于处理请求的线程 - 即使在异步处理中,HttpContext 也会随着您的请求在线程之间流动,但您永远不会有两个线程处理同一个请求(除非您尝试生成自己的线程)。如果您尝试生成自己的线程,则根本无法使用这种方式,因为 HttpContext 实例仅在请求被处理之前存在,但您的自定义线程生命周期可能会更长。

    所以你使用的代码只是这个的过于复杂的版本:

    Context context = httpContext.Items["Context"] as Context;
    if (context == null)
    {
        context = new Context();
        httpContext.Items["Context"] = context;
    }
    

    此外,如果此代码来自您的数据访问层,则说明设计错误。数据访问层处理数据访问,应该独立于上层处理——包括HTTP请求处理。这意味着您的GetContextPerRequest 方法不属于数据访问层。

    【讨论】:

    • 刚读了你的答案,想知道我是否理解正确。是否有可能两个或多个线程在执行异步工作时可以在同一个 HttpContext 上工作,并且上下文会自动切换/同步(您也可以将 HttpContext.Current 作为参数传递给新线程)?在这种情况下,您应该在设置 HttpContext.Items[] 时实现锁定,以确保它不会在其他线程之一中发生?
    • 还是像 Session.Items 一样,执行的线程获得独占读/写锁(或副本),并且在线程完成之前没有其他线程可以使用它?
    【解决方案3】:

    我用这种方式解决了我的问题:

    1. 添加对 system.web 的引用
    2. 使用system.web;在我的数据访问层中
    3. 在 Method consractor 中从 GetContextPerRequest() 创建一个对象

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-17
      • 1970-01-01
      • 2013-10-30
      • 2010-12-07
      • 1970-01-01
      • 2020-11-16
      • 1970-01-01
      • 2011-10-20
      相关资源
      最近更新 更多