2012-02-14 96 views
1

我有一个REST WCF Web服务(.NET 3.5,不使用REST Starter Kit)我想创建一个自定义错误处理程序。它通过IIS 7.5作为Web应用程序中的.svc文件运行。 编辑:也许还值得一提;它通过HTTPS运行。错误处理IIS 7.5中的REST风格的WCF服务与.NET 3.5

在.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

可能重复? http://stackoverflow.com/questions/9312652/errors-and-restful-wcf/9353713#9353713 – nadavy 2012-02-19 22:39:44

回答

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); 
    } 
}