C# 数据交换格式 面向对象开发
数据交换格式
最近做梅州医院接口,数据交换格式不是常见的xml或json,“输入输出参数是以“^、$、|”分割的字符串”。
----------------- ↓↓↓ 接口数据格式说明 ↓↓↓ -------------------
入参格式: inputData
业务编号^医疗机构编号^操作员编号^业务周期号^医院交易流水号^中心编码^入参^联机标志^
其中入参:
以“|”分隔,详见每个交易的参数表, 分项之间使用管道分割符‘|’分割,最后必须要以管道分割符号‘|’结尾,不以‘|’开始。如果入参为多条记录,记录之间以‘$’分割,不同数据项之间以‘|’分割
说明:中心修改参数的原则:只增不减,增加的参数加在参数列表的最后,不在中间插入参数。
----------------- ↑↑↑ 接口数据格式说明 ↑↑↑ -------------------
程序架构设计
通过以上数据交换格式,程序架构设计如下:
基于面向对象开发,每一个业务的request body(BusinessBody)与参数(InputDateBase)、response body(ResponseBody)与参数(OutputDateBase)建立实体,以属性来对应参数字段。
1、业务Body类:
/// <summary>
/// 接口交易主体:
/// 业务编号^医疗机构编号^操作员编号^业务周期号^医院交易流水号^中心编码^入参^联机标志^
/// </summary>
public class BusinessBody
{
/// <summary>
/// 交易实体构造函数:实例化后需要手动指定中心编码
/// </summary>
/// <param name="businessType">业务类型</param>
public BusinessBody(string businessType)
{
this.InputDateList = new List<InputDateBase>();
}
/// <summary>
/// 交易实体构造函数
/// </summary>
/// <param name="businessType">业务类型</param>
/// <param name="pactCode">合同单位编码</param>
public BusinessBody(string businessType,Neusoft.HISFC.Models.Base.Pact pact)
{
this.InputDateList = new List<InputDateBase>();
}
#region 属性
/// <summary>
/// 业务编号(4位)宏定义, 分别对应后台的一项业务操作
/// </summary>
public string BusinessType { get; set; }
/// <summary>
/// 定点医疗机构编号
/// </summary>
public string HospitalNO { get; set; }
/// <summary>
/// 操作员编号(8位)医院分配给操作员的唯一标识
/// </summary>
public string OperCode { get; set; }
/// <summary>
/// 业务周期号(最大36位)操作员签到时,中心返回给his的业务周期号。
/// </summary>
public string OperOnlineNo { get; set; }
/// <summary>
/// 医院交易流水号(发送方交易流水号)(最大30位)
/// </summary>
public string BusinessNO { get; set; }
/// <summary>
/// 中心编码:梅州传 441400异地就医传异地的统筹区号
/// </summary>
public string CenterCode { get; set; }
/// <summary>
/// 入参:以“|”分隔,详见每个交易的参数表, 分项之间使用管道分割符‘|’分割,
/// 最后必须要以管道分割符号‘|’结尾,不以‘|’开始。如果入参为多条记录,
/// 记录之间以‘$’分割,不同数据项之间以‘|’分割
/// 说明:
/// 中心修改参数的原则:只增不减,增加的参数加在参数列表的最后,不在中间插入参数。
/// </summary>
public List<InputDateBase> InputDateList { get; set; }
/// <summary>
/// 联机标志:梅州:固定传1:联机。
/// </summary>
public string ConnetFlag { get; set; }
#endregion 属性
#region 方法
/// <summary>
/// 返回交易
/// </summary>
/// <returns></returns>
public string GetText()
{
string text = string.Empty;
Class.Function.AddStringCaret(this.BusinessType, ref text);
Class.Function.AddStringCaret(this.HospitalNO, ref text);
Class.Function.AddStringCaret(this.OperCode, ref text);
Class.Function.AddStringCaret(this.OperOnlineNo, ref text);
Class.Function.AddStringCaret(this.BusinessNO, ref text);
Class.Function.AddStringCaret(this.CenterCode, ref text);
string inputDate = string.Empty;
if (this.InputDateList!=null)
{
foreach (var item in this.InputDateList)
{
Class.Function.AddStringSegment(item.GetText(), ref inputDate);
}
inputDate = inputDate.TrimEnd('$');
}
Class.Function.AddStringCaret(inputDate, ref text);
Class.Function.AddStringCaret(this.ConnetFlag, ref text);
return text;
}
#endregion 方法
}
2、响应Body类:
/// <summary>
/// 交易返回实体 by chen.fch@2017-12-05
/// 中心交易流水号^联脱机标志^输出参数^
/// </summary>
public class ResponseBody
{
public ResponseBody()
{
OutputDateList = new List<OutputDateBase>();
}
/// <summary>
/// 中心交易流水号:中心交易流水号(最大30位)中心返回
/// </summary>
public string ContenBusinessNo { get; set; }
/// <summary>
/// 联脱机标志:对联脱机的方案,就诊登记时返回该笔业务的联脱机标志,针对联机项目,该字段不用。
/// </summary>
public string CennetFlag { get; set; }
/// <summary>
/// 输出参数实体
/// </summary>
public List<OutputDateBase> OutputDateList { get; set; }
/// <summary>
/// 输出参数文本
/// </summary>
public string OutputDateText { get; set; }
/// <summary>
/// 将交易返回文本赋值到实体
/// </summary>
/// <param name="outputText"></param>
public int InitModel(string outputText,ref string errMsg)
{
try
{
string[] ssTemp = Class.Function.SplitStringCaret(outputText);
this.ContenBusinessNo = ssTemp[0];
this.CennetFlag = ssTemp[1];
this.OutputDateText = ssTemp[2];
}
catch (Exception ex)
{
errMsg = ex.Message;
return -1;
}
return 1;
}
}
3、请求入参抽象类:
/// <summary>
/// 入参基础类:处理实现转换为Text格式 by chen.fch@2017-12-05
/// </summary>
public abstract class InputDateBase
{
/// <summary>
/// 获取入参文本
/// </summary>
/// <returns>返回实体转换文本</returns>
public abstract string GetText();
}
4、响应出参抽象类:
/// <summary>
/// 交易返回抽象类 by chen.fch@2017-12-05
/// </summary>
public abstract class OutputDateBase
{
/// <summary>
/// 将交易返回文本转换成实体
/// </summary>
/// <param name="text">响应文本</param>
public abstract void InitModel(string text);
}
5、共通函数类(Function)添加拼接入参和解析出参字符串:
#region 拼接入参
/// <summary>
/// 添加以^分隔的属性
/// </summary>
/// <param name="addValue"></param>
/// <param name="strText"></param>
public static void AddStringCaret(string addValue, ref string strText)
{
strText = strText + addValue+ "^";
}
/// <summary>
/// 添加以|分隔的属性
/// </summary>
/// <param name="addValue"></param>
/// <param name="strText"></param>
public static void AddStringFilter(string addValue, ref string strText)
{
strText = strText + addValue + "|";
}
/// <summary>
/// 添加以$分隔的属性
/// </summary>
/// <param name="addValue"></param>
/// <param name="strText"></param>
public static void AddStringSegment(string addValue, ref string strText)
{
strText = strText + addValue + "$";
}
/// <summary>
/// 获取入参
/// </summary>
/// <param name="t">入参实体</param>
/// <returns>返回入参文本</returns>
public static string GetText<T>(T t)
{
string text = string.Empty;
// 设置属性默认值
PropertyInfo[] propertys = typeof(T).GetProperties();
foreach (var property in propertys)
{
object obj = property.GetValue(t, null);
AddStringFilter(obj == null ? string.Empty : obj.ToString(), ref text);
}
return text;
}
#endregion 拼接入参
#region 解析出参
/// <summary>
/// 拆分以^分隔的文本
/// </summary>
/// <param name="addValue"></param>
/// <param name="strText"></param>
public static string[] SplitStringCaret(string strText)
{
return strText.Split('^');
}
/// <summary>
/// 拆分以|分隔的文本
/// </summary>
/// <param name="addValue"></param>
/// <param name="strText"></param>
public static string[] SplitStringFilter(string strText)
{
return strText.Split('|');
}
/// <summary>
/// 拆分以$分隔的文本
/// </summary>
/// <param name="addValue"></param>
/// <param name="strText"></param>
public static string[] SplitStringSegment(string strText)
{
return strText.Split('$');
}
/// <summary>
/// 解析出参
/// </summary>
/// <typeparam name="T">返回实体</typeparam>
/// <param name="t">解析实体</param>
/// <param name="text">出参文本</param>
public static void InitModel<T>(T t,string text)
{
if (string.IsNullOrEmpty(text.Trim()))
{
return;
}
string[] ssTemp = SplitStringFilter(text);
// 设置属性默认值
PropertyInfo[] propertys = typeof(T).GetProperties();
int n = 0;
foreach (var property in propertys)
{
if (ssTemp.Length > n)
{
property.SetValue(t, ssTemp[n++], null);
}
}
}
#endregion 解析出参
6、入参与出参实体类:
/// <summary>
/// 4.3.2.11费用结算撤销(2430)
/// </summary>
public class CancelBalance:Base.InputDateBase
{
//编号说明类型约束备注
//1就诊流水号VARCHAR2(20)NOT NULL同登记时的就诊流水号
public string 就诊流水号 { get; set; }
//2单据号VARCHAR2(20)NOT NULL调用需要撤销的单据号
public string 单据号 { get; set; }
//3结算日期VARCHAR2(14)
public string 结算日期 { get; set; }
//4经办人VARCHAR2(20)NOT NULL医疗机构操作员姓名
public string 经办人 { get; set; }
//5是否保存处方标志VARCHAR2(3)二级代码,1:保存;0:不保存
public string 是否保存处方标志 { get; set; }
//6开发商标识VARCHAR2(20)
public string 开发商标识 { get; set; }
//7交易流水号VARCHAR2(22)异地就医
public string 交易流水号 { get; set; }
public override string GetText()
{
return Class.Function.GetText<CancelBalance>(this);
}
}
/// <summary>
/// 4.3.2.11费用结算撤销(2430)
/// </summary>
public class CancelBalanceResponse:Base.OutputDateBase
{
//编号说明类型约束备注
//1对账日期VARCHAR2(8)YYYYMMDD,跨省异地就医时使用
public string 对账日期 { get; set; }
public override void InitModel(string text)
{
Class.Function.InitModel<CancelBalanceResponse>(this, text);
}
}
结束语,以上架构使数据交换格式的字符串处理变成面向对象操作,这样能大大提高程序的可维护性。