在和SAP进行系统对接时,提供的是RFC接口,每个接口函数写一个调用方法的话会比较麻烦,现对其进行一些封装,通过字段映射的方式去实现接口的调用。
1、首先,新建一个类,以函数名作为类名,类成员为传参参数,如果传递的参数是一个表的话,将其封装成一个类对象,如下图:
public class ZSDIE002
{
/// <summary>
/// 表头
/// </summary>
public HEADER HEADER { get; set; }
//public ITEM ITEM { get; set; }
//public KBERT KBERT { get; set; }
/// <summary>
/// 物料明细
/// </summary>
public List<ITEM> ITEM { get; set; }
/// <summary>
/// 价格明细
/// </summary>
public List<KBERT> KBERT { get; set; }
}
2、将步骤1创建的类作为参数,返回值table名也传递进来
/// <summary>
/// SAP函数调用
/// </summary>
/// <typeparam name="T">传参model</typeparam>
/// <param name="requestInfo"></param>
/// <param name="funName">函数名</param>
public static DataResponseInfo<DataTable> SAPRequestApi<T>(T requestInfo, string returnName) where T : class
{
var responseInfo = new DataResponseInfo<DataTable>();
try
{
var destination = SAPRFCHelper.GetSAPConnection();
//获取SAPmodel类属性
Type t = requestInfo.GetType();
IRfcFunction function = destination.Repository.CreateFunction(t.Name);//SAP接口函数
//获取函数类的属性对象
PropertyInfo[] PropertyList = t.GetProperties();
foreach (PropertyInfo propertyInfo in PropertyList)
{
//获取内表
IRfcTable item = function.GetTable(propertyInfo.Name);
IRfcStructure struSAP = item.Metadata.LineType.CreateStructure();
object proValue = propertyInfo.GetValue(requestInfo, null);
if (proValue == null)
continue;
//判断类成员是否为List集合
if (propertyInfo.PropertyType.Name == typeof(List<>).Name)
{
dynamic dList = proValue;
foreach (object d in dList)
{
IRfcStructure struList = item.Metadata.LineType.CreateStructure();
GetStruTable(item, struList, d);
}
}
else
{
//获取属性值
GetStruTable(item, struSAP, proValue);
}
function.SetValue(propertyInfo.Name, item);
}
//执行函数
function.Invoke(destination);
IRfcTable returnTable = function.GetTable(returnName);
DataTable dataTable = returnTable.Count > 0 ? SAPRFCHelper.RFCTableToDataTablex(returnTable) : null;
if (dataTable == null || dataTable.Rows.Count <= 0)
{
responseInfo.Msg = "SAP没有返回数据";
return responseInfo;
}
//客户编码 BUT000-PARTNER CHAR 10
//消息状态 TYPE CHAR 1 S为处理正确 / E为错误
//消息 MESSAGE CHAR 255
DataRow dr = dataTable.Rows[0];
string TYPE = string.Empty;
string MESSAGE = string.Empty;
if (dataTable.Columns.Contains("TYPE"))
{
TYPE = dr["TYPE"].ToString();
MESSAGE = dr["MESSAGE"].ToString();
if (TYPE.ToLower() != "s")
{
responseInfo.Msg = "SAP处理失败:" + MESSAGE;
return responseInfo;
}
}
else
{
TYPE = dr["ZTYPE"].ToString();
MESSAGE = dr["ZMESSAGE"].ToString();
if (TYPE.ToLower() != "s")
{
responseInfo.Msg = "SAP处理失败:" + MESSAGE;
return responseInfo;
}
}
responseInfo.Msg = "SAP处理成功:" + MESSAGE;
responseInfo.IsSuccess = true;
responseInfo.Data = dataTable;
return responseInfo;
}
catch (Exception ex)
{
responseInfo.Msg = ex.Message;
}
return responseInfo;
}
PS:如果传参的list集合的话,做字段映射的时候,需要通过取巧实现获取object类型的对象遍历,取巧方式如下图:
PropertyInfo[] PropertyList = t.GetProperties();
foreach (PropertyInfo propertyInfo in PropertyList)
{
//获取内表
IRfcTable item = function.GetTable(propertyInfo.Name);
IRfcStructure struSAP = item.Metadata.LineType.CreateStructure();
object proValue = propertyInfo.GetValue(requestInfo, null);
if (proValue == null)
continue;
//判断类成员是否为List集合
if (propertyInfo.PropertyType.Name == typeof(List<>).Name)
{
//将值转为dynamic 类型去遍历
dynamic dList = proValue;
foreach (object d in dList)
{
IRfcStructure struList = item.Metadata.LineType.CreateStructure();
GetStruTable(item, struList, d);
}
}
else
{
//获取属性值
GetStruTable(item, struSAP, proValue);
}
function.SetValue(propertyInfo.Name, item);
}