我有一个REST WCF Web服务(.NET 3.5,不使用REST Starter Kit)我想为它创建一个自定义错误处理程序。它通过IIS 7.5在Web应用程序中作为.svc文件运行。 编辑:可能也值得一提;它正在通过HTTPS运行。
.svc.cs文件中的主要服务类:
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class Service
{
[WebGet(UriTemplate = "/units/{id}", ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json), OperationContract]
public Unit GetUnit(string id) {
...
}
...
}
的web.config:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<services>
<service name="WebReservationService.Service">
<endpoint address="" binding="webHttpBinding" contract="WebReservationService.Service"/>
</service>
</services>
</system.serviceModel>
<connectionStrings configSource="WebSettingsConnectionStrings.config"/>
<system.web>
<compilation debug="true"/>
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="AuthModule" type="WebReservationService.AuthModule"/>
</modules>
</system.webServer>
<appSettings configSource="WebClientAuthentication.config"/>
</configuration>
我尝试创建一个IErrorHandler类,并尝试通过web.config使用它,但无法触发它。还尝试通过IHttpModule错误处理程序捕获错误,但这也不会触发。目前我在每个WebGet / WebInvoke中手动捕获错误,但是没有捕获序列化错误或未处理的URI等,更不用说它为代码添加了不必要的混乱。
我知道有一些显而易见的东西我不见了,但我遇到的答案似乎不适用于我的配置。有什么建议吗?
感谢。
修改 刚尝试使用自定义WebServiceHostFactory来应用自定义WebHttpBehavior。工厂和行为都运行并且错误处理程序正在创建 - HandleError和ProvideFault永远不会被调用:
public class ServiceFactory : WebServiceHostFactory
{
public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)
{
ServiceHost host = CreateServiceHost(typeof(Service), baseAddresses);
host.Description.Endpoints[0].Behaviors.Add(new ServiceBehavior());
return host;
}
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
return base.CreateServiceHost(serviceType, baseAddresses);
}
}
public class ServiceBehavior : WebHttpBehavior
{
protected override void AddServerErrorHandlers(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
endpointDispatcher.ChannelDispatcher.ErrorHandlers.Clear();
endpointDispatcher.ChannelDispatcher.ErrorHandlers.Add(new ServiceErrorHandler());
}
}
public class ServiceErrorHandler : IErrorHandler
{
public bool HandleError(Exception error)
{
return true;
}
public void ProvideFault(Exception error, System.ServiceModel.Channels.MessageVersion version, ref System.ServiceModel.Channels.Message fault)
{
throw new NotImplementedException();
}
}
答案 0 :(得分:0)
解决了它。我需要创建一个自定义ServiceHost并在该ServiceHost的OnOpening方法中添加错误处理程序。还必须从我的web.config中取出服务。
public class ServiceFactory : WebServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
ServiceHost host = new RestServiceHost(typeof(Service), baseAddresses);
host.AddServiceEndpoint(serviceType, new WebHttpBinding(), baseAddresses[0]);
return host;
}
}
public class RestServiceHost : WebServiceHost
{
public RestServiceHost() : base() { }
public RestServiceHost(Type serviceType, params Uri[] baseAddresses) : base(serviceType, baseAddresses) { }
protected override void OnOpening()
{
base.OnOpening();
foreach (var endpoint in base.Description.Endpoints)
{
if (endpoint.Behaviors.Find<ServiceBehavior>() == null)
{
endpoint.Behaviors.Add(new ServiceBehavior());
}
}
}
}
public class ServiceBehavior : WebHttpBehavior
{
protected override void AddServerErrorHandlers(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
endpointDispatcher.ChannelDispatcher.ErrorHandlers.Clear();
endpointDispatcher.ChannelDispatcher.ErrorHandlers.Add(new ServiceErrorHandler());
}
}
public class ServiceErrorHandler : IErrorHandler
{
public bool HandleError(Exception error)
{
return true;
}
public void ProvideFault(Exception error, System.ServiceModel.Channels.MessageVersion version, ref System.ServiceModel.Channels.Message fault)
{
Utils.HandleException(error, true);
}
}