0

我有一种情况,我正在构建一个托管在 IIS 上的 Web 服务,该服务需要许可证文件在文件系统上才能成功启动。我想知道我应该将执行许可证检查的代码放在哪里,以防止网站实际启动。

我发现有一个函数Application_Start但是直到有人发出初始请求才会调用它。

理想情况下,当 IIS 管理员尝试启动网站本身时,应用程序会检查许可证并在 Windows 事件日志中记录错误。这可能吗?如果没有,是否有针对这种情况的最佳实践?

4

1 回答 1

4

轰炸整个网站,因为其中一部分使用未注册的组件是非常糟糕的形式。

为此,我可以在您的类的静态构造函数中放入一些东西来检查许可,然后如果找不到您的许可要求,则抛出异常(任何都可以),如下所示:

public static MyComponent
{
    static MyComponent()
    {
         // Check for licensing here.
         if (!<licensing condition>)
         {
             // Bomb the app.
             throw new InvalidOperationException("Component is not licensed.");
         }
    }
}

如果您真的想轰炸整个网站,那么您很可能必须在 ASP.NET 之外执行此操作,并编写一个ISAPI 过滤器(注意,您必须在非托管代码中执行此操作)并将其安装在IIS 服务器。

或者,您可以实现IHttpModule接口。在Init方法实现中,您可以检查您的许可要求。如果未设置要求,则抛出异常,如下所示:

public class MyLicensingHttpModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
         // Check for licensing here.
         if (!<licensing condition>)
         {
             // Bomb the app.
             throw new InvalidOperationException("Component is not licensed.");
         }            
    }
}

(请注意,您仍然必须注册IHttpModule实现

更好的解决方案是实施IHttpModule,但设置一个标志,您的库/组件可以根据需要访问:

public class MyLicensingHttpModule : IHttpModule
{
    // Set when the application is initialized
    public static IsLicensed { get; private set; }

    public void Init(HttpApplication context)
    {
         // Check for licensing here.  Set
         // the flag accordingly.
         IsLicensded = <licensing condition>;
    }
}

随后将在每个构造函数和/或静态构造函数中检查该标志以确保合规性:

public class MyComponentA
{
     static MyComponentA()
     {
          // Check here.
          if (!MyLicensingHttpModule.IsLicensed)
          {
              // Bomb the *type*.
              throw new InvalidOperationException(
                  "MyComponentA is not licensed.");
          }
     }
}

public class MyComponentB
{
     public MyComponentB()
     {
          // Or check on a per-instance basis.  You'd do
          // this if you needed properties on the class level
          // to be available regardless.  This is the
          // *less* likely scenario.
          if (!MyLicensingHttpModule.IsLicensed)
          {
              // Bomb the *instance*.
              throw new InvalidOperationException(
                  "MyComponentA is not licensed.");
          }
     }
}

这将强制安装模块(没有它,标志未设置,这将导致抛出异常),并且应该让您有机会挂钩使用您的组件的每个页面请求,并根据需要阻止使用。

如果你真的走这条路,我必须再次强调,轰炸整个应用程序的形式非常糟糕,你应该在使用它时真正关注你的组件;这不是你真正需要做的。

开发人员很可能有其他页面不使用您的组件,而使用其他应该可以正常呈现的付费组件。

此外,如果您连接到每个请求,您应该确保您不会做任何会导致性能下降的事情。这也将是糟糕的形式。这就是为什么您设置一次标志,然后在需要时进行简单检查的原因。

于 2012-07-17T18:00:47.100 回答