SAP .NET Connector:封送.NET类型时抛出系统异常

时间:2008-12-19 18:18:51

标签: interface marshalling sap saprfc sap-connector

我的应用程序向SAP发送大量数据。为此,它构建了一个SAP表对象并将其发送出去。我有点经常得到这个错误,但不可靠:

System exception thrown while marshaling .NET type 20081219 to RFCTYPE_BCD
   at SAP.Connector.Rfc.RfcMarshal.NetFieldToRfcField(Object src, RFCTYPE type, Encoding encoding, Byte[] dest, Int32 offset, Int32 len, Int32 charSize, Int32 decimals)
   at SAP.Connector.Rfc.RfcStructureUtil.ToRfcStructure(Object obj, Byte[] dest, Type t, Encoding encoding, Boolean isUnicode, PropertyInfo[] propinfos, RfcStructInfo structInfo)
   at SAP.Connector.Rfc.RfcStructureUtil.GetITabFromList(SAPConnection conn, Object list, Type t, RfcStructInfo structInfo, Int32 itab)
   at SAP.Connector.Rfc.RfcClient.PrepareClientParameters(Type classType, MethodInfo m, Boolean isTQRfc, Object[] MethodParamsIn, RFC_PARAMETER[]& paramsIn, RFC_PARAMETER[]& paramsOut, RFC_TABLE[]& tables, ParameterMap[]& paramMaps)
   at SAP.Connector.Rfc.RfcClient.RfcInvoke(SAPClient proxy, String method, Object[] methodParamsIn)
   at SAP.Connector.SAPClient.SAPInvoke(String method, Object[] methodParamsIn)

奇怪的是,每次都不会发生这种情况。此外,它抱怨的.NET类型,“20081219”是我传递的数据(日期) - 不是类型。我认为该字段的类型是RFCTYPE.RFCTYPE_TIME

有关如何解决此间歇性错误的任何建议?在调用SAP RFC之间是否应该清除某种状态?


更新

根据要求,这是调用SAP的代码:

Using sapConnection As New MySapProxy(ConnectionString)
  sapConnection.Connection.Open()
  sapConnection.TheSapRfcICall(SapOpCode, Nothing, Nothing, sapTable, ResultTable)
End Using

我想也许多个线程正在使用相同的连接。使用SAP.Connector.GetNewConnection代替并没有改变任何东西。


更新

即使我运行单个线程,似乎也会出现此问题!这是什么交易??

有没有办法禁用连接池以查看是否修复了它?


更新

@Igal Serban的回答似乎对我有用。我明天早上会检查日志,并(希望)奖励赏金!非常感谢。


更新

根据要求,我的librfc32.dll版本是6403.3.78.4732。

4 个答案:

答案 0 :(得分:1)

更新4:第二个想法,我不认为librfc版本很重要。异常似乎来自托管代码。我能想到的选择是:

  • 尝试在单线程版本上使用调试器。
  • 神奇的方式。即使没有找到错误(那是在sap或你的代码)。只是改变你做生意的方式就可以让它消失。它很丑,但有时很实用。无论如何,您的方案的推荐方法似乎是使用连接池,而不是为每个请求创建新的代理对象。所以可以使用类似这样的(未经测试的)代码:

MySapProxy proxy = new MySapProxy(); // do this only once.

// and in you main loop:
using (proxy.Connection = Connection.GetConnection(connectionString))
{
    proxy.TheSapRfcICall(SapOpCode, Nothing, Nothing, sapTable, ResultTable)
}

此示例隐式使用连接池。可以从配置文件中控制使用。

更新3:请检查您的librfc32.dll版本和日期?它应该位于system32目录或您的应用程序目录中或%path%。

中的某个位置

更新2: Sap笔记就像kb文章一样。我不知道是否可以免费访问sdn.sap.com中的注释,因此我已将其发送到您的邮箱。

更新1: SAP Note 1000057声明:

  

在多线程重载下,可能会出现类型为RfcMarshalException的异常,并引用System.Xml.Xsl.XsltException作为内部异常。

虽然不完全是你收到的例外。值得一试。

补丁可作为此笔记的附件。

**更新0:**只是一个猜测。但我建议看一下线程问题。这是堆栈吗?你可以在你调用sap代码的代码上发布这个部分吗?

答案 1 :(得分:1)

修改

我仍然认为这与映射有关。我相信RFCTYPE_BCD类型是十进制(Business Connector Decimal),因此难以将日期值推入其中(有时可能会工作吗?)。我建议重新生成代理,或者在收到错误时记录正在编组的数据。这样的事情(对不起 - 我们使用自己的代理层,所以我不熟悉Business Connector):

您可以将以下内容翻译成VB(以及sapTable结构的格式):

Using sapConnection As New MySapProxy(ConnectionString)
  sapConnection.Connection.Open()
  try {
    sapConnection.TheSapRfcICall(SapOpCode, Nothing, Nothing, sapTable, ResultTable)
  } catch (Exception e) {
    StringBuilder sb = new StringBuilder();
    foreach (Field f in sapTable.Fields) {
      sb.AppendLine(f.Name + "=" f.Value);
    }
    sb.AppendLine(e.StackTrace);
    File.AppendAllText("C:\\Exception_" + DateTime.Now.ToString("u") + ".txt", sb.ToString());
  }
End Using

我知道这很痛苦,但是当发生错误时,只需快速而肮脏地将一些数据吐出来。

======

从您发布的描述中,我能想出的最好的可能是您正在尝试将日期值(20081219)编组到时间字段中?

您可以在try / catch中包装该调用并记录发送给SAP的表的值并在此处发布吗?我希望数据中有线索。

我知道,通过向SAP发布Web服务帖子,SAP非常关注其日期时间和格式。值。

答案 2 :(得分:0)

看起来它试图将整数或字符串(由于ToString()而无法告诉)转换为BCD(二进制编码的十进制)类型。

<击>

只是一个猜测,希望它有所帮助。

更新:

猜不是。

使用相同连接的多个线程?这可能不是一个好主意,除非你使用锁定,这将使线程毫无意义。我确信SAP支持连接池,因此在它自己的线程中打开连接(每个线程一个)。

答案 3 :(得分:0)

可能是日期格式问题吗?你说它不会每次都发生。
因此,当你通过20081202时,它需要'12'作为日期部分,02作为一个月部分。没关系。
但是当你通过20081219时,它会尝试解析19个月并抛出异常? 请与SAP管理员核实。