I implemented a class that implements IErrorHandler interface to log WCF errors. One of the things that I'd like to do is log who the identity of the user than connected to my service when an exception occurred. All my logging occurs in HandleError() method of IErrorHandler interface, but since HandleError() may not have current operation context, I can't get the SecurityContext.PrimaryIdentity. I've come up with the following code to capture things that may not be available in HandleError method, but I'm not sure this will work in all cases.
public class MyErrorHandler : IErrorHandler
{
private IIdentity identity;
public bool HandleError(Exception error)
{
// Do something with identity
return false;
}
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
this.identity = Operation.Current.SecurityContext.PrimaryIdentity;
}
}
The code above seems to be working, but are there any gotchas?
Thanks!
For some reason, I thought that the class was created every time there was an exception. In any case, I was able to solve my issue by using Dictionary property of Exception object to store custom data that I wanted to log with my exception.
Related
I am using a WCF Service and I have implemented IErrorHandler. In the HandleError method, I want to retrieve the caller's username in order to set a ThreadContext property for Log4Net (to save the username along with the exception details in SQL Server)
My code is working well if I avoid trying to retrieve the caller's username.
This is the line of code inside the HandleError method which is returning a NullReferenceException:
string username = ServiceSecurityContext.Current.WindowsIdentity.Name;
It seems that at the point the HandleError method of IErrorHandler kicks in, the original caller information has been disposed.
Does anyone have any idea how I can retrieve the caller's username inside the HandlerError method of IErrorHandler?
Thanks for your help!
Thanks to those who responded to help. My security appears to be configured correctly but I cannot retrieve the username in the HandleError method of the IErrorHandler interface in the WCF service. However, I am able to retrieve the username in the ProvideFault method. So, I declared a class level variable in the ErrorHandler (IErrorHandler) class which is set during the ProvideFault method and then read and logged with the exception in the ErrorHandler method. This is a "workaround" and not my preference, but unfortunately I cannot seem to access the security context inside the HandleError method.
Here is a sample of the code:
public class ErrorHandler : IErrorHandler, IServiceBehavior
{
private string username = null;
public bool HandleError(Exception error)
{
//Log the exception along with the username.
//...logging call including the username class member string...
//Return true to indicate we have performed our behaviour.
return true;
}
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
//Retrieve the username.
username = ServiceSecurityContext.Current.WindowsIdentity.Name;
}
}
If you get this exception then you probably do not have security configured correctly. See also this answer: https://stackoverflow.com/a/2869481/106567
Using a Class Level variable seems to have a side effect. The same instance of the handler seems to be used for every error handled (to be confirmed). So if 2 errors are raised at the exact same time, I don't know how it will react. So instead, in ProvideFault, I used the exception received as argument to transport the username to the HandleError method. An exception has a «Data» property which is a dictionary. I just add two key-value pairs (one for PrimaryIdentity and one for WindowsIdentity). In HandleError, I retrieved the information in the Data property of the exception received as argument.
Ok, so I have asked another question on the same topic here and while I did not get a direct answer there I've pulled together some code that I got working to do what I wanted. Question is, does this way break some OOP principle?
What I wanted
Use proper OOP to declare fault types on a service
Have one catch block in the client side that can handle multiple types of exceptions thrown from the service
Have one HandleException method per fault class that has its own implementation
On the client side have just one exception block understand what exception was thrown and call the respective HandleException method from the corresponding fault class
How I got it working
Declared a fault contract on server for each exception type that inherits from a base exception type
[DataContract]
public class BusinessRuleViolationFault : BaseFault
{
public BusinessRuleViolationFault(string message)
: base(message)
{
}
}
[DataContract]
public class SomeOtherViolationFault : BaseFault
{
public SomeOtherViolationFault(string message)
: base(message)
{
}
}
[DataContract]
public abstract class BaseFault
{
public BaseFault(string message)
{
Message = message;
}
}
On the client side I created partial classes of the same fault types as above and implemented the handle exception method in it. I had to do this on the client side since if I created this method on the service side it would not get serialized and be available via the proxy.
public partial class BusinessRuleViolationFault : BaseFault
{
public override void HandleException()
{
MessageBox.Show("BusinessRuleViolationFault handled");
}
}
public partial class SomeOtherViolationFault : BaseFault
{
public override void HandleException()
{
MessageBox.Show("SomeOtherViolationFault handled");
}
}
public abstract partial class BaseFault
{
public abstract void HandleException();
}
Then created an extension method on the faultexception class as per Christians code which I have marked as accepted answer in my previous post. This basically used reflection to get me the name of the fault exception class that was thrown.
Then in my client catch block I used that name to create an instance of the locally created partial class which has the handle exception method.
What I am curious to know is, have I broken some OOP principle here?
Is this OOP at all?
I dont want multiple if else statement in this one catch block or have multiple catch blocks. What is your opinion on the tradeoff of using one catch block to gain performance and lose it with reflection by trying to figure out what class method to call?
Thanks for your time and patience ...
I don't understand exactly why reflection is needed here (as described in the previous posted question). I simply do this in my code and it works fine:
try
{
proxy.CallServiceMethod(message);
}
catch (Exception e)
{
if (e is FaultException<BaseFault>)
{
BaseFault exceptionToHandle =
(e as FaultException<BaseFault>).Detail as BaseFault;
exceptionToHandle.HandleException();
}
}
Aside from the unnecessary reflection, I don't see anything wrong with the way you have implemented this (from an OOP point of view at least).
after a server call my client catches an exception with the following message
"The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error."
Also, note I tried the configuration in WCF "The server did not provide a meaningful reply"
but still didn't work.
Please note, that I debug the service to the end, and the data is successfully populated but at the client end when the data is supposed to appear it just crashes with the mentioned exception.
Any help appreciated.
I figured out the reason behind this that the proxy was wrongly generated for an enum type, it was generated as a string so it failed and gave me out that exception
If someone else comes across this same exception, with the same behavior of debugging to the end in the server, but getting the exception on the return to the client, another possible cause is an uninitialized enum in the return data contract where the enum has explicit values, but no explicit zero value.
[ServiceContract]
public interfact IMyService
{
[OperationContract]
MyResult DoSomething();
}
[DataContract]
public class MyResult
{
[DataMember]
public OperationStatus Status {get; set;}
[DataMember]
public string ErrorText {get; set;}
}
[DataContract]
public enum Operation Status
{
[EnumMember]
Success = 1,
[EnumMember]
Failure = 2
}
public class MyService : IMyService
{
public MyResult DoSomething()
{
var result = new MyResult();
// ... do work, but don't set any properties on result ...
return result;
}
}
The reason the error happens in this scenario is that result.Status defaults to zero, but the data contract does not provide any means to serialize it, since it is not one of the explicitly defined enum values.
The solution (assuming you really do need this enum with explicit integer values) is to either set the enum value in the return object, or provide a default (zero) value.
[DataContract]
public enum Operation Status
{
[EnumMember]
Unknown = 0,
[EnumMember]
Success = 1,
[EnumMember]
Failure = 2
}
--Bill
if your web service return a DataTable, it must have TableName;
look at https://stackoverflow.com/a/5894732/775811
The cause of this error for me was a missing FaultContractAttribute(typeof(FaultModel)) on the Server function interface (The one marked with OperationContract attribute).
When the FaultException< FaultModel >() was thrown on the server side the client side was throwing - CommunicationException: "The server did not provide a meaningful reply this might be caused by a contract mismatch, a premature session shutdown or an internal server error.".
Hope will help someone.
This happened to me on a new system (Windows 10) after trying to call a Windows Workflow service. Other WCF service calls were working, but trying to call the workflow activity (a xamlx WF4 service) received this error.
Trying to browse to the service.xamlx file resulted in a blank screen. That eventually led me to this other answer (the IIS8 specific answer), which is to add the HTTP Activation feature under IIS Services:
WCF on IIS8; *.svc handler mapping doesn't work
I am researching Prism v2 by going thru the quickstarts. And I have created a WCF service with the following signature:
namespace HelloWorld.Silverlight.Web
{
[ServiceContract(Namespace = "http://helloworld.org/messaging")]
[AspNetCompatibilityRequirements(RequirementsMode =
AspNetCompatibilityRequirementsMode.Allowed)]
public class HelloWorldMessageService
{
private string message = "Hello from WCF";
[OperationContract]
public void UpdateMessage(string message)
{
this.message = message;
}
[OperationContract]
public string GetMessage()
{
return message;
}
}
}
When I add a service reference to this service in my silverlight project it generates an interface and a class:
[System.ServiceModel.ServiceContractAttribute
(Namespace="http://helloworld.org/messaging",
ConfigurationName="Web.Services.HelloWorldMessageService")]
public interface HelloWorldMessageService {
[System.ServiceModel.OperationContractAttribute
(AsyncPattern=true,
Action="http://helloworld.org/messaging/HelloWorldMessageService/UpdateMessage",
ReplyAction="http://helloworld.org/messaging/HelloWorldMessageService/UpdateMessageResponse")]
System.IAsyncResult BeginUpdateMessage(string message, System.AsyncCallback callback, object asyncState);
void EndUpdateMessage(System.IAsyncResult result);
[System.ServiceModel.OperationContractAttribute(AsyncPattern=true, Action="http://helloworld.org/messaging/HelloWorldMessageService/GetMessage", ReplyAction="http://helloworld.org/messaging/HelloWorldMessageService/GetMessageResponse")]
System.IAsyncResult BeginGetMessage(System.AsyncCallback callback, object asyncState);
string EndGetMessage(System.IAsyncResult result);
}
public partial class HelloWorldMessageServiceClient : System.ServiceModel.ClientBase<HelloWorld.Core.Web.Services.HelloWorldMessageService>, HelloWorld.Core.Web.Services.HelloWorldMessageService {
{
// implementation
}
I'm trying to decouple my application by passing around the interface instead of the concrete class. But I'm having difficulty finding examples of how to do this. When I try and call EndGetMessage and then update my UI I get an exception about updating the UI on the wrong thread. How can I update the UI from a background thread?
I tried but I get UnauthorizedAccessException : Invalid cross-thread access.
string messageresult = _service.EndGetMessage(result);
Application.Current.RootVisual.Dispatcher.BeginInvoke(() => this.Message = messageresult );
The exception is thrown by Application.Current.RootVisual.
Here is something I like doing... The service proxy is generated with an interface
HelloWorldClient : IHelloWorld
But the problem is that IHelloWorld does not include the Async versions of the method. So, I create an async interface:
public interface IHelloWorldAsync : IHelloWorld
{
void HelloWorldAsync(...);
event System.EventHandler<HelloWorldEventRgs> HelloWorldCompleted;
}
Then, you can tell the service proxy to implement the interface via partial:
public partial class HelloWorldClient : IHelloWorldAsync {}
Because the HelloWorldClient does, indeed, implement those async methods, this works.
Then, I can just use IHelloWorldAsync everywhere and tell the UnityContainer to use HelloWorldClient for IHelloWorldAsync interfaces.
Ok, I have been messing with this all day and the solution is really much more simple than that. I originally wanted to call the methods on the interface instead of the concreate class. The interface generated by proxy class generator only includes the BeginXXX and EndXXX methods and I was getting an exception when I called EndXXX.
Well, I just finished reading up on System.Threading.Dispatcher and I finally understand how to use it. Dispatcher is a member of any class that inherits from DispatcherObject, which the UI elements do. The Dispatcher operates on the UI thread, which for most WPF applications there is only 1 UI thread. There are exceptions, but I believe you have to do this explicitly so you'll know if you're doing it. Otherwise, you've only got a single UI thread. So it is safe to store a reference to a Dispatcher for use in non-UI classes.
In my case I'm using Prism and my Presenter needs to update the UI (not directly, but it is firing IPropertyChanged.PropertyChanged events). So what I have done is in my Bootstrapper when I set the shell to Application.Current.RootVisual I also store a reference to the Dispatcher like this:
public class Bootstrapper : UnityBootstrapper
{
protected override IModuleCatalog GetModuleCatalog()
{
// setup module catalog
}
protected override DependencyObject CreateShell()
{
// calling Resolve instead of directly initing allows use of dependency injection
Shell shell = Container.Resolve<Shell>();
Application.Current.RootVisual = shell;
Container.RegisterInstance<Dispatcher>(shell.Dispatcher);
return shell;
}
}
Then my presenter has a ctor which accepts IUnityContainer as an argument (using DI) then I can do the following:
_service.BeginGetMessage(new AsyncCallback(GetMessageAsyncComplete), null);
private void GetMessageAsyncComplete(IAsyncResult result)
{
string output = _service.EndGetMessage(result);
Dispatcher dispatcher = _container.Resolve<Dispatcher>();
dispatcher.BeginInvoke(() => this.Message = output);
}
This is sooooo much simpler. I just didn't understand it before.
Ok, so my real problem was how to decouple my dependency upon the proxy class created by my service reference. I was trying to do that by using the interface generated along with the proxy class. Which could have worked fine, but then I would have also had to reference the project which owned the service reference and so it wouldn't be truly decoupled. So here's what I ended up doing. It's a bit of a hack, but it seems to be working, so far.
First here's my interface definition and an adapter class for the custom event handler args generated with my proxy:
using System.ComponentModel;
namespace HelloWorld.Interfaces.Services
{
public class GetMessageCompletedEventArgsAdapter : System.ComponentModel.AsyncCompletedEventArgs
{
private object[] results;
public GetMessageCompletedEventArgsAdapter(object[] results, System.Exception exception, bool cancelled, object userState) :
base(exception, cancelled, userState)
{
this.results = results;
}
public string Result
{
get
{
base.RaiseExceptionIfNecessary();
return ((string)(this.results[0]));
}
}
}
/// <summary>
/// Create a partial class file for the service reference (reference.cs) that assigns
/// this interface to the class - then you can use this reference instead of the
/// one that isn't working
/// </summary>
public interface IMessageServiceClient
{
event System.EventHandler<GetMessageCompletedEventArgsAdapter> GetMessageCompleted;
event System.EventHandler<AsyncCompletedEventArgs> UpdateMessageCompleted;
void GetMessageAsync();
void GetMessageAsync(object userState);
void UpdateMessageAsync(string message);
void UpdateMessageAsync(string message, object userState);
}
}
Then I just needed to create a partial class which extends the proxy class generated by the service reference:
using System;
using HelloWorld.Interfaces.Services;
using System.Collections.Generic;
namespace HelloWorld.Core.Web.Services
{
public partial class HelloWorldMessageServiceClient : IMessageServiceClient
{
#region IMessageServiceClient Members
private event EventHandler<GetMessageCompletedEventArgsAdapter> handler;
private Dictionary<EventHandler<GetMessageCompletedEventArgsAdapter>, EventHandler<GetMessageCompletedEventArgs>> handlerDictionary
= new Dictionary<EventHandler<GetMessageCompletedEventArgsAdapter>, EventHandler<GetMessageCompletedEventArgs>>();
/// <remarks>
/// This is an adapter event which allows us to apply the IMessageServiceClient
/// interface to our MessageServiceClient. This way we can decouple our modules
/// from the implementation
/// </remarks>
event EventHandler<GetMessageCompletedEventArgsAdapter> IMessageServiceClient.GetMessageCompleted
{
add
{
handler += value;
EventHandler<GetMessageCompletedEventArgs> linkedhandler = new EventHandler<GetMessageCompletedEventArgs>(HelloWorldMessageServiceClient_GetMessageCompleted);
this.GetMessageCompleted += linkedhandler;
handlerDictionary.Add(value, linkedhandler);
}
remove
{
handler -= value;
EventHandler<GetMessageCompletedEventArgs> linkedhandler = handlerDictionary[value];
this.GetMessageCompleted -= linkedhandler;
handlerDictionary.Remove(value);
}
}
void HelloWorldMessageServiceClient_GetMessageCompleted(object sender, GetMessageCompletedEventArgs e)
{
if (this.handler == null)
return;
this.handler(sender, new GetMessageCompletedEventArgsAdapter(new object[] { e.Result }, e.Error, e.Cancelled, e.UserState));
}
#endregion
}
}
This is an explicit implementation of the event handler so I can chain together the events. When user registers for my adapter event, I register for the actual event fired. When the event fires I fire my adapter event. So far this "Works On My Machine".
Passing around the interface (once you have instantiated the client) should be as simply as using HelloWorldMessageService instead of the HelloWorldMessageServiceClient class.
In order to update the UI you need to use the Dispatcher object. This lets you provide a delegate that is invoked in the context of the UI thread. See this blog post for some details.
You can make this much simpler still.
The reason the proxy works and your copy of the contract does not is because WCF generates the proxy with code that "Posts" the callback back on the calling thread rather than making the callback on the thread that is executing when the service call returns.
A much simplified, untested, partial implementation to give you the idea of how WCF proxies work looks something like:
{
var state = new
{
CallingThread = SynchronizationContext.Current,
Callback = yourCallback
EndYourMethod = // assign delegate
};
yourService.BeginYourMethod(yourParams, WcfCallback, state);
}
private void WcfCallback(IAsyncResult asyncResult)
{
// Read the result object data to get state
// Call EndYourMethod and block until the finished
state.Context.Post(state.YourCallback, endYourMethodResultValue);
}
The key is the storing of the syncronizationContext and calling the Post method. This will get the callback to occur on the same thread as Begin was called on. It will always work without involving the Dispatcher object provided you call Begin from your UI thread. If you don't then you are back to square one with using the Dispatcher, but the same problem will occur with a WCF proxy.
This link does a good job of explaining how to do this manually:
http://msdn.microsoft.com/en-us/library/dd744834(VS.95).aspx
Just revisiting old posts left unanswered where I finally found an answer. Here's a post I recently wrote that goes into detail about how I finally handled all this:
http://www.developmentalmadness.com/archive/2009/11/04/mvvm-with-prism-101-ndash-part-6-commands.aspx
Pulling my hair out trying to debug this one. Earlier this morning, this code was working fine, and I can't see what I've changed to break it. Now, whenever I try to open an nHibernate session, I'm getting the following error:
Test method BCMS.Tests.Repositories.BlogBlogRepositoryTests.can_get_recent_blog_posts threw exception: System.TypeInitializationException: The type initializer for 'NHibernate.Cfg.Environment' threw an exception. ---> System.Runtime.Serialization.SerializationException: Type is not resolved for member 'Castle.DynamicProxy.Serialization.ProxyObjectReference,Rhino.Mocks, Version=3.5.0.1337, Culture=neutral, PublicKeyToken=0b3305902db7183f'..
Any thoughts on how to debug what's going on here?
I hit the same issue as you - in my case it was with NLog's static method:
LogManager.GetCurrentClassLogger()
I'd replaced the current thread's principal with a Rhinomocks stub:
var identity = MockRepository.GenerateStub<IIdentity>();
identity.Stub(x => x.IsAuthenticated).Return(true);
var principal = MockRepository.GenerateStub<IPrincipal>();
principal.Stub(x => x.Identity).Return(identity);
Thread.CurrentPrincipal = principal;
Running unit tests for my code threw the same exception from the original question.
The stack trace:
at System.AppDomain.get_Evidence()
at System.AppDomain.get_EvidenceNoDemand()
at System.AppDomain.get_Evidence()
at System.Configuration.ClientConfigPaths.GetEvidenceInfo(AppDomain appDomain, String exePath, String& typeName)
at System.Configuration.ClientConfigPaths.GetTypeAndHashSuffix(AppDomain appDomain, String exePath)
at System.Configuration.ClientConfigPaths..ctor(String exePath, Boolean includeUserConfig)
at System.Configuration.ClientConfigPaths.GetPaths(String exePath, Boolean includeUserConfig)
at System.Configuration.ClientConfigurationHost.RequireCompleteInit(IInternalConfigRecord record)
at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
at System.Configuration.BaseConfigurationRecord.GetSection(String configKey)
at System.Configuration.ClientConfigurationSystem.System.Configuration.Internal.IInternalConfigSystem.GetSection(String sectionName)
at System.Configuration.ConfigurationManager.GetSection(String sectionName)
at NLog.Config.XmlLoggingConfiguration.get_AppConfig()
at NLog.LogFactory.get_Configuration()
at NLog.LogFactory.GetLogger(LoggerCacheKey cacheKey)
at NLog.LogFactory.GetLogger(String name)
at NLog.LogManager.GetCurrentClassLogger()
at MyClassHere...
So as you can see from the stack trace an attempt to read the config file is made, which won't work - why? Because the now mocked current principal is no longer the WindowsPrincipal that we had originally - it's now a mocked principal which won't have any sort of windows file access.
Thinking off the cuff here's a couple of ways to fix this issue.
Inject the logger into my class so that it can be stubbed (I probably should be doing this anyway I suppose..). This would allow me to use a stub for the Thread principal.
Modify the existing WindowsPrincipal (or create another based on it) on the thread to add in the roles required to call my methods.
-- UPDATE --
To fix my issue, in the end I decided to run with my first suggestion above. To avoid writing my own abstraction of the NLog Logger I just leveraged what was offered from Common.Logging. Class constructors now accept an ILog as one of their parameters, and the Unity config to inject the logger just looks like this:
container.RegisterType<ILog>(new TransientLifetimeManager(), new InjectionFactory(x => LogManager.GetCurrentClassLogger()));
Meanwhile, my unit tests now allow me to pass in a mocked logger.
var logger = MockRepository.GenerateStub<ILog>();
Some more info... it seems to be related to switching the Thread.CurrentPrincipal to a mocked IPrincipal implementation. I do all my security checks in my domain model inside the entities. The entity's methods check Thread.CurrentPrincipal.IsInRole() before modifying properties on the entity.
So, in order to test the entity's methods, I have to set different users (contributor user, moderator user, etc.) before I make my entity method calls.
I haven't figured out why this was working fine yesterday.
Here's an example of my Mocked IPrincipal:
private static IPrincipal _blogContributorUser = null;
public static IPrincipal BlogContributorUser
{
get
{
if (null == _blogContributorUser)
{
var identity = MockRepository.GenerateStub<IIdentity>();
identity.Stub(p => p.Name).Return("BlogContributor").Repeat.Any();
var principal = MockRepository.GenerateStub<IPrincipal>();
principal.Stub(p => p.Identity).Return(identity).Repeat.Any();
principal.Stub(p => p.IsInRole(UserRoles.BlogContributor)).Return(true).Repeat.Any();
principal.Stub(p => p.IsInRole(UserRoles.CommentContributor)).Return(true).Repeat.Any();
principal.Stub(p => p.IsInRole(UserRoles.TagContributor)).Return(true).Repeat.Any();
_blogContributorUser = principal;
}
return _blogContributorUser;
}
}
I have the same issue. It looks like that it has trouble reading the config file, since CurrentPrincipal is changed. I have moved all that has to be initialized from the config file, before replacing the CurrentPrincipal (for example, opened NHibernate session, initialized Unity and that kind of stuff), and everything works after that. Of course, this is not a solution, just a workaround figured out by a desperate man.
Errors like this usually indicate versioning issues.
What I suspect may be happening is that both RhinoMocks and NHibernate are making use of Castle.DynamicProxy type, but they are asking for different versions of that type.
Did you recently uprade RhinoMocks or NHibernate to a newer version?
If this isn't the issue, then more information would be helpful - do all tests fail, or just this particular one?
edit You may also wish to try adding these lines to your Properties\AssemblyInfo.cs file:
[assembly: InternalsVisibleTo("Rhino.Mocks")]
[assembly: InternalsVisibleTo("Castle.DynamicProxy")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
In case the error is related to mocking IPrincipal and/or IIdentity with RhinoMocks or Moq the solution is actually quite simple: don't use those frameworks but create simple fake types instead.
Here is an example for a simple "allow everything" implementation:
public class FakeIdentity : IIdentity
{
public string Name { get { return "IntegrationTest"; } }
public string AuthenticationType { get { return "Kerberos"; } }
public bool IsAuthenticated { get { return true; } }
}
public class FakePrincipal : IPrincipal
{
public FakePrincipal() { this.Identity = new FakeIdentity(); }
public IIdentity Identity { get; private set; }
public bool IsInRole(string role) { return true; }
}
If you need more complexity take a look at the System.Security.Principal.GenericPrincipal class.