2012-02-14 21 views
1

REST WCF Webサービス(.NET 3.5、RESTスターターキットを使用していません)があります。カスタムエラーハンドラーを作成したいと思います。 IIS 7.5を介してWebアプリケーションで.svcファイルとして実行されています。 編集:おそらく言及する価値もあります。それはHTTPS上で実行されています。.NET 3.5のIIS 7.5でのRESTful WCFサービスでのエラー処理

.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

答えて

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); 
    } 
} 
関連する問題