最近写的通用SAP接口,支持入参object,出参动态参数。也支持泛型(代码没有贴出)
截图代码可能不是很全。建议下载代码。
1.创建连接
private RfcDestination CreateDestination()
{
RfcConfigParameters rfcPar = new RfcConfigParameters();
try
{
rfcPar.Add(RfcConfigParameters.Name, Guid.NewGuid().ToString().Substring(0,4));
rfcPar.Add(RfcConfigParameters.AppServerHost, serverHost);
rfcPar.Add(RfcConfigParameters.Client, client);
rfcPar.Add(RfcConfigParameters.User, user);
rfcPar.Add(RfcConfigParameters.Password, password);
rfcPar.Add(RfcConfigParameters.SystemNumber, systemNumber);
rfcPar.Add(RfcConfigParameters.Language, "EN");
rfcPar.Add(RfcConfigParameters.ConnectionIdleTimeout, connectionIdleTimeout);
//连接到SAP
RfcDestination dest = RfcDestinationManager.GetDestination(rfcPar);
// RfcConfigParameters.loadConfiguration
return dest;
}
catch (Exception ex)
{
var str = ex.Message;
while (ex.InnerException != null)
{
ex = ex.InnerException;
str += ex.ToString()+";"; // ex.Message;
}
throw new Exception("CreateDestination:" + str);
}
}
2.创建RCf
private IRfcFunction createFunciton(string FunName)
{
if (connect == null)
{
connect = CreateDestination();
}
RfcRepository rfcrep = connect.Repository;
IRfcFunction myfun = rfcrep.CreateFunction(FunName);
return myfun;
}
3.入口
/// <summary>
/// 请求 RFC 接口
/// </summary>
/// <param name="FunName">接口名称</param>
/// <param name="import">传入的参数</param>
public ExpandoObject Execute(string FunName, Dictionary<string, object> import)
{
try
{
if (import == null)
{
throw new Exception("传入的参数pairs为null");
}
IRfcFunction myfun = createFunciton(FunName);
//入参配置
FunSetValue(import, ref myfun);
//调用接口
myfun.Invoke(connect);
//返回结果
return FunGetValue(myfun);
}
catch (Exception)
{
throw;
}
}
4.入参
//设置参数
private void FunSetValue(Dictionary<string, object> import, ref IRfcFunction myfun)
{
foreach (var item in import)
{
Type valueType = item.Value.GetType();
//值类型和字符串
if (valueType.FullName == "System.String" || IsNumericType(valueType))
{
myfun.SetValue(item.Key, item.Value);
}
//table类型
else if (valueType.FullName == "System.Data.DataTable")
{
//表入参配置
IRfcTable options = myfun.GetTable(item.Key);
DataTable dt = item.Value as DataTable;
for (int i = 0; i < dt.Rows.Count; i++)
{
options.Append();
for (int j = 0; j < dt.Columns.Count; j++)
{
options.SetValue(dt.Columns[j].ColumnName, dt.Rows[i][dt.Columns[j].ColumnName].ToString());
}
}
}
else
{
IRfcStructure struc = myfun.GetStructure(item.Key);
struc = GetRfcStructureForObj(item.Value, struc);
myfun.SetValue(item.Key, struc);
}
}
}
5.出参
private ExpandoObject SonFunGetValue(IRfcStructure rst, RfcFieldMetadata item)
{
ExpandoObject sonResult = new ExpandoObject();
if (item.DataType.ToString() == "STRUCTURE")
{
//取结构值
IRfcStructure st = rst.GetStructure(item.Name);
Dictionary<RfcFieldMetadata, IRfcField> sondata = st.ToDictionary(a => a.Metadata);
var mylist = new List<ExpandoObject>();
foreach (var Info in sondata)
{
mylist.Add(SonFunGetValue(rst, Info.Key));
}
((IDictionary<string, object>)sonResult).Add(item.Name, mylist);
}
else
if (item.DataType.ToString() == "TABLE")
{
IRfcTable data = rst.GetTable(item.Name);
DataTable dTable = ToDataTable(data);
((IDictionary<string, object>)sonResult).Add(item.Name, dTable);
}
else
{
((IDictionary<string, object>)sonResult).Add(item.Name, rst.GetValue(item.Name));
}
return sonResult;
}
//返回结果
private ExpandoObject FunGetValue(IRfcFunction myfun)
{
ExpandoObject Result = new ExpandoObject();
Dictionary<RfcParameterMetadata, IRfcParameter> results = myfun.ToDictionary(product => product.Metadata);
foreach (var item in results)
{
if (item.Key.DataType.ToString() == "STRUCTURE")
{
//取结构值
IRfcStructure st = myfun.GetStructure(item.Key.Name);
Dictionary<RfcFieldMetadata, IRfcField> sondata = st.ToDictionary(a => a.Metadata);
var mylist = new List<ExpandoObject>();
foreach (var Info in sondata)
{
mylist.Add(SonFunGetValue(st, Info.Key));
}
((IDictionary<string, object>)Result).Add(item.Key.Name, mylist);
}
else if (item.Key.Direction.ToString() == "EXPORT")
{
((IDictionary<string, object>)Result).Add(item.Key.Name, myfun.GetValue(item.Key.Name));
}
else
if (item.Key.DataType.ToString() == "TABLE")
{
IRfcTable data = myfun.GetTable(item.Key.Name);
DataTable dTable = ToDataTable(data);
((IDictionary<string, object>)Result).Add(item.Key.Name, dTable);
}
}
//返回结果
return Result;
}
6.其他工具
//通用结果返回
private T getDate<T>(IRfcFunction myfun)
{
T t = default(T);
//获取T类中的所有属性
PropertyInfo[] TpropertyInfo = typeof(T).GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic);
//用反射自动创建泛型对象
t = System.Activator.CreateInstance<T>();
foreach (PropertyInfo pInfo in TpropertyInfo)
{
string pInfo_name = pInfo.Name;
//给属性赋值
pInfo.SetValue((object)t, TypeTransaction(myfun, pInfo), null);
}
return t;
}
/// <summary>
/// 子对象动态执行装箱操作
/// </summary>
/// <param name="myfun">IRfcStructure</param>
/// <param name="pInfo">属性的类型</param>
/// <returns>装箱后的对象</returns>
private object TypeTransactionStructure(IRfcStructure myfun, PropertyInfo pInfo)
{
Object obj = new object();
try
{
string keyName = pInfo.Name;
if (pInfo.PropertyType.FullName == "System.Data.DataTable")
{
IRfcTable data = myfun.GetTable(keyName);
DataTable dTable = ToDataTable(data);
}
else
{
Type valueType = Type.GetType(pInfo.PropertyType.FullName);
//值类型和字符串
if (pInfo.PropertyType.FullName == "System.String" || IsNumericType(valueType))
{
obj = myfun.GetValue(keyName);
}
else
{
Assembly assembly = Assembly.GetExecutingAssembly(); // 获取当前程序集
Object son = assembly.CreateInstance(pInfo.PropertyType.FullName);
//取结构值
IRfcStructure st = myfun.GetStructure(pInfo.Name);
获取类中的所有属性
PropertyInfo[] TpropertyInfo = son.GetType().GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic);
用反射自动创建泛型对象
//t = System.Activator.CreateInstance <pInfo.PropertyType.FullName> ();
foreach (PropertyInfo Info in TpropertyInfo)
{
string pInfo_name = pInfo.Name;
//给属性赋值
Info.SetValue((object)son, TypeTransactionStructure(st, Info), null);
}
obj = son;
}
}
}
catch (Exception e)
{
throw e;
}
return obj;
}
/// <summary>
/// 主对象动态执行装箱操作
/// </summary>
/// <param name="myfun">IRfcFunction</param>
/// <param name="pInfo">属性</param>
/// <returns>装箱后的对象</returns>
private object TypeTransaction(IRfcFunction myfun, PropertyInfo pInfo)
{
Object obj = new object();
try
{
string keyName = pInfo.Name;
if (pInfo.PropertyType.FullName == "System.Data.DataTable")
{
IRfcTable data = myfun.GetTable(keyName);
obj = ToDataTable(data);
}
else
{
Type valueType = Type.GetType(pInfo.PropertyType.FullName);
//值类型和字符串
if (pInfo.PropertyType.FullName == "System.String" || IsNumericType(valueType))
{
obj = myfun.GetValue(keyName);
}
else
{
Assembly assembly = Assembly.GetExecutingAssembly(); // 获取当前程序集
Object son = assembly.CreateInstance(pInfo.PropertyType.FullName);
//取结构值
IRfcStructure st = myfun.GetStructure(pInfo.Name);
获取类中的所有属性
PropertyInfo[] TpropertyInfo = son.GetType().GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic);
用反射自动创建泛型对象
//t = System.Activator.CreateInstance <pInfo.PropertyType.FullName> ();
foreach (PropertyInfo Info in TpropertyInfo)
{
string pInfo_name = pInfo.Name;
//给属性赋值
Info.SetValue((object)son, TypeTransactionStructure(st, Info), null);
}
obj = son;
}
}
}
catch (Exception e)
{
throw e;
}
return obj;
}
//判斷是否值類型
private static bool IsNumericType(Type o)
{
return !o.IsClass && !o.IsInterface && o.GetInterfaces().Any(q => q == typeof(IFormattable));
}
public DataTable ToDataTable(IRfcTable myrfcTable)
{
DataTable loTable = new DataTable();
int liElement = 0;
for (liElement = 0; liElement <= myrfcTable.ElementCount - 1; liElement++)
{
RfcElementMetadata metadata = myrfcTable.GetElementMetadata(liElement);
loTable.Columns.Add(metadata.Name);
}
foreach (IRfcStructure Row in myrfcTable)
{
DataRow ldr = loTable.NewRow();
for (liElement = 0; liElement <= myrfcTable.ElementCount - 1; liElement++)
{
RfcElementMetadata metadata = myrfcTable.GetElementMetadata(liElement);
ldr[metadata.Name] = Row.GetString(metadata.Name);
}
loTable.Rows.Add(ldr);
}
return loTable;
}