[英]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.