簡體   English   中英

使用.NET 3.5的IIS 7.5中的RESTful WCF服務中的錯誤處理

[英]Error handling in RESTful WCF service in IIS 7.5 with .NET 3.5

我有一個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();
    }
}

解決了。 我需要制作一個自定義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);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM