处理来自外部系统的结果代码查找 - 如果需要,引发异常
本文关键字:如果 异常 查找 外部 系统 代码 结果 处理 | 更新日期: 2023-09-27 18:34:35
我有一个使用http post/get的应用程序界面,使用xml消息。接口系统返回一条消息,其中包含结果代码和请求的数据。结果代码由 3 部分组成,代码和子代码按类型分组(登录名、请求...某些代码/子代码是登录成功等消息,其他代码/子代码是无效登录或无效消息请求等异常。
我正在尝试找到一种方法来处理结果代码,并在需要时抛出带有消息的异常。如果结果代码仅供参考,只需将返回消息上的消息应用于 api 使用者即可。我正在研究责任链,但试图通过它遇到大脑障碍。
示例代码
类型。。。。法典。。子代码....描述
登录。。。0....0....请求成功
登录。。。0.....nn...登录成功。距离到期
还有"nn"天登录。。。21....1....登录失败。(用户标识/密码错误(。
登录。。。21....4.......已经登录
登录。。。21....5....系统资源不可用。无法分配安全对象
请求.50....2..........服务 语法
无效请求.50....3..........服务 无效属性
请求.50....4..........服务 批处理文件已存在
带有结果代码(代码、子代码(的结果消息:
登录管理器结果 0, 0 是信息性的,都很好
登录结果 0, 24855 是帐户良好,无泄漏
如果登录结果有 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; }
}
}
您尝试实现的是"模式匹配"机制,责任链模式是OOP中同一事物的另一个名称。C# 中没有内置的方式来进行结构模式匹配,尽管您可以在 SO 或其他地方查看,但有一些通用的想法。
如果这只是一次性的事情,您可以尝试只列出规则列表,看起来像成对(谓词,操作(。然后,您的 Match 方法将逐个浏览规则,谓词返回 true 的第一个规则是匹配并执行其操作。
为什么这可能比责任链更好?好吧,你不需要很多额外的对象,你可以使用匿名lambda来指定谓词和动作,然后你的规则列表将只适合一页代码,将易于阅读,更改,审查。
下面是一个可以进一步改进的快速示例。添加更多规则时,可以通过将一些常见谓词或谓词的一部分以及某些操作或部分操作提取到命名委托中来进一步提高可读性。
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");
}