5

我们正在开发一个 3 层应用程序,并且我们被允许使用最新最好的(MVC2、IIS7.5、WCF、SQL2k8 等)。应用程序层通过 WCF 服务向各种 Web 应用程序公开。由于我们同时控制服务端和客户端,因此我们决定使用 net.tcp 绑定,因为它们的性能优于 HTTP。

我们希望在 Web 应用程序和服务上使用ELMAH进行错误记录。这是我的问题。有很多关于将 ELMAH 与 WCF 结合使用的信息,但都是针对 HTTP 绑定的。有谁知道您是否/如何将 ELMAH 与暴露非 HTTP 端点的 WCF 服务一起使用?

我的猜测是否定的,因为 ELMAH 需要 HttpContext,这需要在 web.config 中将AspNetCompatibilityEnabled标志设为 true。来自MSDN

IIS 7.0 和 WAS 允许 WCF 服务通过 HTTP 以外的协议进行通信。但是,在启用了 ASP.NET 兼容模式的应用程序中运行的 WCF 服务不允许公开非 HTTP 终结点。当服务接收到它的第一条消息时,这样的配置会生成一个激活异常。

如果确实不能将 ELMAH 与具有非 HTTP 端点的 WCF 服务一起使用,那么接下来的问题是:我们能否以不需要 HttpContext 的方式使用 ELMAH?或者更一般地说(以免犯薄金属尺错误),有没有办法将 ELMAH 与具有非 HTTP 端点的 WCF 服务一起使用?

注意:我知道我们可以下载 Elmah 源代码并将其更改为添加 shim 或删除 HttpContext 依赖项,但我试图避免分叉代码。

4

4 回答 4

5

不。ELMAH 是一个 HTTP 模块,除非您提供 HTTP 请求,否则 ELMAH 不会做任何事情

于 2010-05-31T05:35:34.727 回答
2

有可能如下

Elmah.ErrorLog.GetDefault(null).Log(new Error(ex));

参考: http ://groups.google.com/group/elmah/browse_thread/thread/9ea4b51420fd5dfa

早些时候,除了 AspNetCompatibility Mode 之外,我还为 WCF 服务尝试了此解决方案,但它不适用于 IIS 托管的 WCF 服务,但它适用于 Visual Studio 中的开发服务器托管的 WCF 服务。因此,我必须对上述解决方案感到满意。

于 2010-06-11T05:27:07.047 回答
0

您是否尝试过使用静态 void AppInitialize() {} 方法对其进行初始化?在初始化 WCF 相关事物时,它适用于非 HTTP 端点。

更多信息请看董文龙的优秀博文:http: //blogs.msdn.com/b/wenlong/archive/2006/01/11/511514.aspx

高温下,

--larsw

于 2010-05-27T18:19:34.497 回答
0

我们将企业库异常处理块与 ELMAH 结合使用来记录异常。它不使用任何 HTTP 模块,而是直接调用日志到 ELMAH。

 public class ErrorHandlerServiceBehaviour : BehaviorExtensionElement, IServiceBehavior
    {
        #region BehaviourExtensionElement Members

        public override Type BehaviorType
        {
            get { return typeof(ErrorHandlerServiceBehaviour); }
        }

        protected override object CreateBehavior()
        {
        return new ErrorHandlerServiceBehaviour();
    }

    #endregion

    #region IServiceBehavior Members

    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
        foreach (ChannelDispatcher channelDispatcher in serviceHostBase.ChannelDispatchers)
        {
            channelDispatcher.ErrorHandlers.Add(new ElmahExceptionHandler());
        }
    }

    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
    }

    #endregion

}

然后是异常处理程序

 public class ElmahExceptionHandler : IErrorHandler
    {
        #region IErrorHandler Members

        public bool HandleError(Exception error)
        {
            return ExceptionPolicy.HandleException(error, "ServiceExceptions");
        }

        public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
        {

        }

        #endregion
    }

然后在 app.config 的企业库异常策略部分

<exceptionHandling>
    <exceptionPolicies>    
    <add name="ServiceExceptions">
        <exceptionTypes>
          <add type="System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
            postHandlingAction="NotifyRethrow" name="Exception">
            <exceptionHandlers>
              <add type="DB.Framework.Logging.ElmahExceptionHandler, DinguBlue.Framework.Logging"
                name="Elmah Exception Handler" />
            </exceptionHandlers>
          </add>
        </exceptionTypes>
      </add>
    </exceptionPolicies>    
</exceptionHandling>

参见例如http://dotnetslackers.com/articles/aspnet/Getting-ELMAH-to-work-with-WCF-services.aspx

于 2011-02-08T01:01:23.220 回答