Elmah for non-HTTP protocol applications OR Elmah without HttpContext
Asked Answered
U

4

5

We are working on a 3-tier application, and we've been allowed to use the latest and greatest (MVC2, IIS7.5, WCF, SQL2k8, etc). The application tier is exposed to the various web applications by WCF services. Since we control both the service and client side, we've decided to use net.tcp bindings for their performance advantage over HTTP.

We would like to use ELMAH for the error logging, both on the web apps and services. Here's my question. There's lots of information about using ELMAH with WCF, but it is all for HTTP bindings. Does anyone know if/how you can use ELMAH with WCF services exposing non-HTTP endpoints?

My guess is no, because ELMAH wants the HttpContext, which requires the AspNetCompatibilityEnabled flag to be true in the web.config. From MSDN:

IIS 7.0 and WAS allows WCF services to communicate over protocols other than HTTP. However, WCF services running in applications that have enabled ASP.NET compatibility mode are not permitted to expose non-HTTP endpoints. Such a configuration generates an activation exception when the service receives its first message.

If it is true that you cannot use ELMAH with WCF services having non-HTTP endpoints, then the follow-up question is: Can we use ELMAH in such a way that doesn't need HttpContext? Or more generally (so as not to commit the thin metal ruler error), is there ANY way to use ELMAH with WCF services having non-HTTP endpoints?

Note: I'm aware that we can download the Elmah source code and change it to add a shim or remove the HttpContext dependency, but I'm trying to avoid forking the code.

Untwist answered 22/5, 2010 at 0:5 Comment(1)
Could check out this for using Elmah in console apps - some of it might be of use in your situation: #841951Yeseniayeshiva
A
5

No. ELMAH is a HTTP module, and unless you are serving HTTP requests, ELMAH won't do anything

Adamina answered 31/5, 2010 at 5:35 Comment(3)
Yeah, that's kind of the conclusion I've come to too. I tried creating fake HttpContext objects and didn't get very far.Untwist
It is possible. See my answer below.Gabbard
this is not true!!! you can use elmah on any code! google groups - scroll to bottomImam
G
2

It is possible as below

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

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

Earlier I tried this solution for WCF service in addition AspNetCompatibility Mode and it didn't worked on IIS hosted WCF service, but it was working on dev server hosted WCF service within Visual Studio. Hence I had to satisfy myself with the above solution.

Gabbard answered 11/6, 2010 at 5:27 Comment(2)
Thank you for your answer. Unfortunately, Visual Studio doesn't support net.tcp bindings for WCF services (or any non-HTTP bindings, for that matter). That means what you tested is really just the standard Elmah behavior for HTTP applications.Untwist
don't forget to add the application name in the config of elmah. it will work!Imam
H
0

Have you tried to use the static void AppInitialize() {} method of initializing it? It works with non-HTTP endpoints when initializing WCF related things.

For more information, see Wenlong Dong's excellent blog post: Link

HTH,

--larsw

Holography answered 27/5, 2010 at 18:19 Comment(1)
I don't see what that gets us. AppInitialize is a possible replacement for Application_Start in non-HTTP applications, but that doesn't fire on every request or create context.Untwist
F
0

We use Enterprise Library Exception Handling block in conjunction with ELMAH to log exceptions. Rather than using any HTTP modules it utilizes calling log to ELMAH directly.

 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

}

Then the ExceptionHandler

 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
    }

then in the enterprise library exception policies section of 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>

see for example http://dotnetslackers.com/articles/aspnet/Getting-ELMAH-to-work-with-WCF-services.aspx

Frere answered 8/2, 2011 at 1:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.