【问题标题】:Share HttpContext code between web and non-web application在 Web 和非 Web 应用程序之间共享 HttpContext 代码
【发布时间】:2008-11-13 07:49:42
【问题描述】:

我有一个 VB.NET 模块,它从资源文件中读取数据,以正确的语言显示文本。这是我的问题 - 此代码在 Web 应用程序和非 Web 应用程序之间共享,在 Web 应用程序中,我使用 System.Web.HttpContext 来确定用户的首选语言,但现在我的 Windows 应用程序甚至无法编译,因为它说 HttpContext 没有定义(我已经尝试为完整的命名空间添加导入 - 没有骰子)。

如果我不能以其他方式解决它,我很想使用某种 try/catch 块,但这不会改变 Windows 应用程序不会在其中引用 HttpContext 进行编译。如果不将这段代码移动到一个新文件中并仅将其包含在 Web 应用程序中(我不拥有该应用程序,所以我宁愿不处理这些影响),我是否还有其他选择来处理这个问题?

如果没有任何意义,请告诉我,我会尽力澄清。

解决方案:我刚刚添加了对 System.Web 的引用,它允许我的应用程序编译。我还将 HttpContext 引用包装在“If HttpContext.Current isnot Nothing Then...End If”块中,如果它没有作为 Web 应用程序运行,这会导致它跳过代码,这正是我正在寻找的。

【问题讨论】:

    标签: asp.net vb.net httpcontext


    【解决方案1】:

    如果您引用 System.Web 程序集,那么您应该有权访问 HttpContext.Current,它是对当前正在运行的 Web 应用程序的 HttpContext 对象的引用。如果应用程序是一个普通的 Win32 应用程序,这个引用应该是一个空指针。因此,在 C# 中,您将使用: if (HttpContext.Current == null) 或者在 VB 中你可以使用: If HttpContext.Current Is Nothing Then

    但是,我从来没有尝试过做这种事情,所以我不能保证结果。让我知道这是否适合您。

    谢谢, C

    【讨论】:

    • 好吧,如果你运行的是 NUnit GUI 工具,它就不起作用,在这种情况下它不为空:(
    【解决方案2】:

    即使应用程序可以编译,你也会遇到 WinApp 中没有 HttpContext 的问题。

    您可以重构 webapp,以便它使用服务而不是 HttpContext。 IContextService 或一堆服务(ICacheService、ISessionService 等)。

    该服务将有两种实现:一种用于使用 HttpContext 的 Web 应用程序,另一种用于 Winapp,其实现将包含确定用户偏好(语言等)的必要逻辑。

    如果首选项存储在服务器上,您将需要实现某种服务来在您的 winapp 和服务器之间进行通信。

    【讨论】:

      【解决方案3】:

      我认为你可以使用一点解耦!

      如果您要创建这样的接口(例如在您的 BLL 层中)

      public interface IPreferredLanguage
      {
           String PeferredLanguage { get; set; }
      }
      

      然后你创建了两个实现:

      在你的网站项目中:

      public class WebPeferredLanguage : IPreferredLanguage
      {
           public String PeferredLanguage
           {
                get
                {
                     return // retrieve the language from the http context
                }
                set
                {
                     // set the preferred language in the HttpContext
                }
           } 
      }
      

      在您的 winforms 项目中:

      public class WinformsPeferredLanguage : IPreferredLanguage
      {
           public String PeferredLanguage
           {
                get; set; // automatic properties
           } 
      }
      

      此后,您使用Inversion of Control(Unity、StructureMap、MicroKernel)在您的 webconfig 中配置应使用 WebPeferredLanguage 的实例,并应在您的 winforms 中返回 WinformsPeferredLanguage 的单例实例。

      在您的代码中,每当您需要了解语言时,您只需向 IoC 容器询问 IPreferredLanguage 的正确实现,它就会返回您配置的类型的对象。

      所以在你的 bll 中你可以编程(例如):

      public String GetEmailMessage()
      {
          var currentLanguage = IoC.Resolve<IPreferredLanguage>().PeferredLanguage;
          return Resources[currentLanguage ].EmailMessage;
      }
      

      写完这篇文章后,我发现您想要一个 VB.NET 解决方案。好吧,这些例子仍然适用,只是语法略有不同(抱歉,如果这样更难阅读)。

      【讨论】:

      • ps,这不是使用 IoC 容器的方式,您应该使用依赖注入来注入 IPrefferedLanguage 实现。
      【解决方案4】:

      您可以将 System.Web.dll 添加到您的应用程序中,然后使用 HttpContext。问题是您的 win 应用程序中没有 HttpContext,因此您应该使用 Web 服务或 WCF 在两个应用程序之间进行通信。

      【讨论】:

        【解决方案5】:

        如果可能,您能做的最好的事情可能是完全消除对在共享程序集中拥有 HTTP 上下文的依赖。

        例如,您提到的使用 HttpContext 获取用户偏好的方法可以重构,以便将语言作为参数给出。当您从 Web 应用程序调用该方法时,您可以从 HttpContext 传递语言,当您从 Windows 应用程序调用它时,您需要从另一个源传递语言。

        【讨论】:

          【解决方案6】:

          你应该使用

          Thread.CurrentUICulture
          

          确定用户语言。 WinForms 和 WebApplication 也支持它。

          .NET 框架在大多数情况下为您设置了它。

          您可以在程序/线程启动时进行设置。在 Web 应用程序中,您可以在 Application_BeginRequest 的 Global.asax.cs 中设置它。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-03-12
            • 1970-01-01
            • 2016-12-23
            • 1970-01-01
            • 1970-01-01
            • 2018-08-27
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多