我将首先展示在非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端点代码,服务可以正常启动,并且可以通过客户端javascript轻松地与wcf托管对象进行通信。但是,自定义错误处理程序不起作用。原因是,在运行webServiceHost.Open()时,不会调用AddServerErrorHandlers()方法。
那么,谁能告诉我这张照片有什么问题?为什么AddServerErrorHandlers()没有被自动调用,就像我使用非ssl端点时一样?
谢谢!
答案 0 :(得分:0)
我将推荐您使用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,这是你应该做的。