IErrorHandler returning wrong message body when HTTP status code is 401 Unauthorized

*爱你&永不变心* 提交于 2019-11-28 13:31:58

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.

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.

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();
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!