簡體   English   中英

WCF服務合同和錯誤處理

[英]WCF service contract and error handling

我正在嘗試托管一個可用作代理/網關的服務,以通用方式調用其他各種服務。 該服務將采用標識要調用的服務的參數以及將其簡單傳遞給“實現”的有效負載字符串。 “網關”負責外部客戶端的身份驗證,並將用戶的身份以及其他“上下文”信息提供給“實現”。

我希望提供無效請求的外部客戶端收到指示錯誤的消息。 但是,由於“網關”服務不知道請求(或響應)應該是什么樣,因此必須依靠“真實”服務給出可靠地指示“錯誤請求”的響應。 還需要提供錯誤消息(對請求的錯誤的易於理解的描述)。 在某些情況下,“實現”具有其自己的授權邏輯,因此類似地,它還必須能夠指示“未授權”,我認為狀態為403的HttpException可以很好地表示這一點。

所有實現者都將在.net中作為WCF服務編寫。

我以為我可以指定服務合同,讓實現拋出狀態代碼為400或403的HttpException,以將錯誤信息提供回“網關”-不必指定故障合同(不存在)一些通用的SOAP錯誤,並且這至少不允許錯誤代碼和消息字符串嗎?)。

現在,我嘗試構建一個POC。 請求有效且實現正常返回的“正常”情況可以正常工作。 但是當出現問題時,我看不到任何獲取錯誤信息的方法。

在控制台應用程序中測試一種服務實現:

private string GetResponse(string req)
{
    try
    {
        using (var proxy = new MapperProxy())
        {
            return proxy.Map(null, req);
        }
    }
    catch (FaultException fe)
    {
        int status = GetStatus(fe);
        switch (status)
        {
            case 400:
                return "400 BAD REQUEST - " + fe.Message;

            case 403:
                return "403 FORBIDDEN - " + fe.Message;

            default:
                return "501 INTERNAL SERVER ERROR";
        }
    }
    catch (Exception ex)
    {
        return "Exception caught: " + ex.ToString();
    }
}

假定WCF服務拋出了狀態代碼為400的HttpException。(服務實現被配置為“在錯誤中包括異常詳細信息”。)如何實現GetStatus(FaultException ex)?

我找到了答案。 我可以通過使實現者拋出SoapFaultException來指示錯誤代碼和消息,從而使用通用的SOAP錯誤。 我可能應該設置Action和屬性以指示這是客戶端還是服務器故障,但這可行:

服務器端:

public string Map(MapperContext context, string payLoad)
{
    string verb = GetFirstWord(payLoad).ToUpper();

    switch (verb)
    {
        case "ECHO":
            return payLoad.Substring(verb.Length).TrimStart();

        case "COP":
            throw new FaultException("Only cops may use this service.", new FaultCode("FORBIDDEN"));

        case "BUG":
            throw new NullReferenceException();
    }

    throw new FaultException("Invalid request; first word must be 'ECHO', 'COP' or 'BUG'.", new FaultCode("BAD REQUEST"));
}

private string GetFirstWord(string request)
{
    for (int i = 0; i < request.Length; i++)
    {
        if (char.IsWhiteSpace(request[i]))
        {
            return request.Substring(0, i);
        }
    }

    return request;
}

修改的客戶端(我的控制台應用程序對其進行測試):

private string GetResponse(string req)
{
    try
    {
        using (var proxy = new MapperProxy())
        {
            return proxy.Map(null, req);
        }
    }
    catch (FaultException fe)
    {
        switch (fe.Code.Name)
        {
            case "BAD REQUEST":
                return "400 BAD REQUEST - " + fe.Message;

            case "FORBIDDEN":
                return "403 FORBIDDEN - " + fe.Message;

            default:
                return "501 INTERNAL SERVER ERROR: " + fe.Message;
        }
    }
    catch (Exception ex)
    {
        return "Exception caught: " + ex.ToString();
    }
}

我認為這足以滿足我的目的。

暫無
暫無

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

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