2012-05-17 36 views
2

我有一個應用程序接口,使用http post/get使用xml消息。接口系統返回帶有結果代碼和請求數據的消息。結果代碼是3部分,代碼和按代碼分類的類型(登錄,請求...)。某些代碼/子代碼是登錄成功等消息,其他代碼則是例外,例如無效登錄或無效消息請求。處理來自外部系統的結果代碼查找 - 如果需要拋出異常

我想找到一種方法來處理結果代碼並根據需要拋出異常。如果結果代碼僅是信息性的,只需將我的返回消息中的消息應用於api消費者。我正在研究責任鏈,但是試圖通過它來解決大腦阻塞問題。

示例代碼
類型.... Code..Subcode ....說明
登錄... 0 0 ..... ..........請求成功
登錄... 0 ..... nn .........登錄成功。 「nn」天才會到期
登錄... 21 .... 1 ..........登錄失敗。 (用戶名/密碼錯誤)。
登錄... 21 .... 4 ..........已經登錄
登錄... 21 .... 5 ..........系統資源不可用。無法分配安全對象
Request.50 .... 2 ..........服務無效語法
Request.50 .... 3 .......... service無效的屬性
Request.50 .... 4 ..........服務批處理文件已經存在與結果代碼(代碼,子碼)

結果消息:
loginmanagerresult 0,0是信息,都好
loginresult 0,24855是佔好,無exipration
如果loginresult有1,2,拋出異常帳戶鎖定

<?xml version="1.0" encoding="UTF-8"?> 
    <loginmanagerresult sessionname="ALBHMROC9040RL1" code="0" subcode="0"> 
     <loginresult code="0" subcode="24855" sectoken="f1044f0aaad65ef2e28d4edc0663716f00000000"></loginresult> 
    </loginmanagerresult> 

我有反序列化到以下對象:不能改變,擴展\繼承,但沒有額外的屬性\功能。

public class LoginResult 
{ 

    private string code = ""; 
    [XmlAttribute("code")] 
    public string Code 
    { 
     get { return code; } 
     set { code = value; } 
    } 

    private string subCode = ""; 
    [XmlAttribute("subcode")] 
    public string SubCode 
    { 
     get { return subCode; } 
     set { subCode = value; } 
    } 

    private string secToken = ""; 
    [XmlAttribute("sectoken")] 
    public string SecToken 
    { 
     get { return secToken; } 
     set { secToken = value; } 
    } 

} 

[XmlRoot("loginmanagerresult")] 
public class LoginManagerResult 
{ 

    private string sessionName = ""; 
    [XmlAttribute("sessionname")] 
    public string SessionName 
    { 
     get { return sessionName; } 
     set { sessionName = value; } 
    } 

    private string code = ""; 
    [XmlAttribute("code")] 
    public string Code 
    { 
     get { return code; } 
     set { code = value; } 
    } 

    private string subCode = ""; 
    [XmlAttribute("subcode")] 
    public string SubCode 
    { 
     get { return subCode; } 
     set { subCode = value; } 
    } 

    private LoginResult loginResult = null; 
    [XmlElement("loginresult", IsNullable = true)] 
    public LoginResult LoginResult 
    { 
     get { return loginResult; } 
     set { loginResult = value; } 
    } 

    private QueryCapabilitiesResult queryCapabilitiesResult = null; 
    [XmlElement("querycapabilitiesresult", IsNullable = true)] 
    public QueryCapabilitiesResult QueryCapabilitiesResult 
    { 
     get { return queryCapabilitiesResult; } 
     set { queryCapabilitiesResult = value; } 
    } 

    private GetMotdResult getMotdResult = null; 
    [XmlElement("getmotdresult", IsNullable = true)] 
    public GetMotdResult GetMotdResult 
    { 
     get { return getMotdResult; } 
     set { getMotdResult = value; } 
    } 

    private LogOutResult logOutResult = null; 
    [XmlElement("logoutresult", IsNullable = true)] 
    public LogOutResult LogOutResult 
    { 
     get { return logOutResult; } 
     set { logOutResult = value; } 
    } 


} 

回答

0

你想實現什麼是「模式匹配」的機制,責任鏈模式是一種別稱在OOP同樣的事情。在C#中沒有內置的方法來完成結構模式匹配,但是您可以在SO或其他地方查看,there are some generic ideas

如果這只是一次性的事情,你可以試着制定一個規則列表,看起來像(Predicate,Action)對。然後你的Match方法會逐個處理規則,並且Predicate返回true的第一條規則是匹配,並且它的Action被執行。

爲什麼這可能比責任鏈更好?好吧,你不需要很多額外的對象,你可以使用匿名lambdas來指定謂詞和動作,然後你的規則列表將只適合在一頁代碼中,將會很容易閱讀,更改,評論。

下面是一個可以進一步改進的簡單例子。當您添加更多規則時,您可以通過將一些常見謂詞或謂詞的部分以及某些動作或動作的一部分抽取到命名委託中來進一步提高可讀性。

public class LoginResult 
{ 
    public string Code { get; set; } 
    public string SubCode { get; set; } 
    public string SecToken { get; set; } 
} 

public static IDictionary<Predicate<LoginResult>, Func<LoginResult, string>> rules = 
    new Dictionary<Predicate<LoginResult>, Func<LoginResult, string>> 
     { 
      { lr => lr.Code == "0" && lr.SubCode != "0", result => "Login successful, days left till expiration: " + result.SubCode }, 
      { lr => lr.Code == "0", _ => "Login successful" }, 
      { lr => lr.Code == "21", _ => ThrowInvalidOperation("Login failed. (Userid/password wrong).") }, 
     }; 

static string ThrowInvalidOperation(string message) 
{ 
    throw new InvalidOperationException(message); 
} 

static string Match(LoginResult result) 
{ 
    foreach (var rule in rules) 
    { 
     if (rule.Key(result)) 
     { 
      return rule.Value(result); 
     } 
    } 

    throw new ArgumentException("Matching rule not found", "result"); 
} 
相關問題