I have implemented IErrorHandler to handle authorization exceptions thrown within the constructor of my restful WCF service. When a general exception is caught my custom typ
After struggling with this for almost a full day I discovered that this was caused by an IIS setting.
Under my API project in IIS, under the Authentication menu I had 'Forms Authentication' set to 'Enabled'. I turned off this 'feature' and the code above started working as expected. I found that this was due to another developer on my team putting code within the web.config file that altered the settings in IIS. Specifically:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
...
<system.web>
<authentication mode="Forms" />
</system.web>
...
</configuration>
Further, I was able to get the Content-Type header to appear correctly by using the ContentType Property on the WebOperationContext OutgoingResponse object.
// Get the outgoing response portion of the current context
var response = WebOperationContext.Current.OutgoingResponse;
// Add ContentType header that specifies we are using JSON
response.ContentType = new MediaTypeHeaderValue("application/json").ToString();
Base on what you write, you throw an exception in the constructor of the service implementation. Because WCF uses reflection to create your service implementation, unless your service are Singleton, you will get a TargetInvocationException.
Example (use LINQPad):
void Main()
{
try
{
Activator.CreateInstance(typeof(Foo));
}
catch(Exception e)
{
e.Message.Dump();
e.GetType().Name.Dump();
}
}
public class Foo
{
public Foo()
{
throw new AuthorizationFailedException();
}
}
public class AuthorizationFailedException : Exception
{
}
Basically, avoid throwing exceptions based on business logic in a constructor. Only do that for handling programming errors.
I am not quite sure how your application is implemented. Based on your description, I suggest using visual studio to debug your ErrorHandler to see whether the exception arrive your callback.
If yes, manually construct your soap fault or response in the way you want.
If not, it means the exception happens before arriving your service operation, it may fail already in Channel stack, in this case, an easy approach is add extra HttpModule to custom or map the response. Or you can try custom the encoder in Channel stack.