【问题标题】:Windows Service Hosting WCF Objects over SSL (https) - Custom JSON Error Handling Doesn't Work通过 SSL (https) 托管 WCF 对象的 Windows 服务 - 自定义 JSON 错误处理不起作用
【发布时间】:2010-06-09 19:51:07
【问题描述】:

我将首先展示在非 ssl (http) 环境中工作的代码。此代码使用自定义 json 错误处理程序,并且所有抛出的错误都会冒泡到客户端 javascript (ajax)。

        // Create webservice endpoint
        WebHttpBinding binding = new WebHttpBinding();

        ServiceEndpoint serviceEndPoint = new ServiceEndpoint(ContractDescription.GetContract(Type.GetType(svcHost.serviceContract + ", " + svcHost.assemblyName)), binding, new EndpointAddress(svcHost.hostUrl));

        // Add exception handler
        serviceEndPoint.Behaviors.Add(new FaultingWebHttpBehavior());

        // Create host and add webservice endpoint
        WebServiceHost webServiceHost = new WebServiceHost(svcHost.obj, new Uri(svcHost.hostUrl));
        webServiceHost.Description.Endpoints.Add(serviceEndPoint);

        webServiceHost.Open();

我还将向您展示 FaultingWebHttpBehavior 类的外观:

public class FaultingWebHttpBehavior : WebHttpBehavior
{
    public FaultingWebHttpBehavior()
    {         
    }

    protected override void AddServerErrorHandlers(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
        endpointDispatcher.ChannelDispatcher.ErrorHandlers.Clear();
        endpointDispatcher.ChannelDispatcher.ErrorHandlers.Add(new ErrorHandler());
    }

    public class ErrorHandler : IErrorHandler
    {
        public bool HandleError(Exception error)
        {
            return true;
        }

        public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
        {
            // Build an object to return a json serialized exception
            GeneralFault generalFault = new GeneralFault();
            generalFault.BaseType = "Exception";
            generalFault.Type = error.GetType().ToString();
            generalFault.Message = error.Message;                

            // Create the fault object to return to the client
            fault = Message.CreateMessage(version, "", generalFault, new DataContractJsonSerializer(typeof(GeneralFault)));
            WebBodyFormatMessageProperty wbf = new WebBodyFormatMessageProperty(WebContentFormat.Json);
            fault.Properties.Add(WebBodyFormatMessageProperty.Name, wbf);

        }
    }
}

[DataContract]
public class GeneralFault
{
    [DataMember]
    public string BaseType;

    [DataMember]
    public string Type;

    [DataMember]
    public string Message;
}

一旦调用 webServiceHost.Open(),就会自动调用 AddServerErrorHandlers() 方法。这设置了自定义 json 错误处理程序,生活很好:-)

问题来了,当我们切换到 SSL (https) 环境时。我现在将向您展示 SSL 的端点创建代码:

        // Create webservice endpoint
        WebHttpBinding binding = new WebHttpBinding();
        ServiceEndpoint serviceEndPoint = new ServiceEndpoint(ContractDescription.GetContract(Type.GetType(svcHost.serviceContract + ", " + svcHost.assemblyName)), binding, new EndpointAddress(svcHost.hostUrl));

        // This exception handler code below (FaultingWebHttpBehavior) doesn't work with SSL communication for some reason, need to resarch...
        // Add exception handler
        serviceEndPoint.Behaviors.Add(new FaultingWebHttpBehavior());

        //Add Https Endpoint
        WebServiceHost webServiceHost = new WebServiceHost(svcHost.obj, new Uri(svcHost.hostUrl));
        binding.Security.Mode = WebHttpSecurityMode.Transport;
        binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
        webServiceHost.AddServiceEndpoint(svcHost.serviceContract, binding, string.Empty);

现在,使用此 SSL 端点代码,服务可以正确启动,并且 wcf 托管对象可以通过客户端 javascript 正常通信。但是,自定义错误处理程序不起作用。原因是,当 webServiceHost.Open() 运行时,AddServerErrorHandlers() 方法永远不会被调用。

那么,谁能告诉我这张照片有什么问题?为什么 AddServerErrorHandlers() 不会像我使用非 ssl 端点那样被自动调用?

谢谢!

【问题讨论】:

    标签: ajax wcf ssl https


    【解决方案1】:

    我会推荐你​​参考 MSDN 文档

    如果传输值由 这 WebHttpBinding(WebHttpSecurityMode), 然后由提供的设置 交通财产生效 对于服务端点。的价值 WebHttpSecurityMode 只能设置在 WebHttpBinding 构造函数 将其作为显式参数并 之后无法再次设置其值 绑定实例已创建。

    见:http://msdn.microsoft.com/en-us/library/bb348328.aspx

    所以你需要传递这个值

    binding.Security.Mode = WebHttpSecurityMode.Transport;
    

    像这样进入你的 .ctor()

    WebHttpBinding binding = new WebHttpBinding(WebHttpSecurityMode.Transport);
    

    我以前从未使用过它,因为我总是将我的绑定声明到 web.config 文件中,但根据 MSDN,这是你应该做的。

    【讨论】:

    • 好吧,我会说这是你的一个很好的发现。坏消息是,它仍然不起作用。该服务的行为完全相同。它启动正确,但永远不会调用 AddServerErrorHandlers(),因此永远不会处理错误...
    • 你调试usign Casini还是IIS?请记住,Casini 与 IIS 不同(例如,它不是多线程的)
    • 图片中都没有。 FaultingWebHttpBehavior() 中的 AddServerErrorHandlers() 方法应在调用 webServiceHost.Open() 期间在服务启动时自动调用(这正是非 SSL (http) 端点发生的情况,它工作得很好。所以,要测试,我只是用 AddServerErrorHandlers() 中的断点启动服务 - 它被 http 端点命中,而不是被 https 端点命中...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-10
    • 1970-01-01
    • 2015-03-14
    • 2019-12-31
    • 2013-01-14
    相关资源
    最近更新 更多