.NET Core 實做連接 SAP 並部署到 App Service

  • 1703
  • 0

前言

最近工作上需要串接 SAP,但是因為現在專案都改用 .NET Core 了,官方的 SAP Connector for Microsoft .NET 主要是支援 .NET Framework,因此就在 NuGet 上面找了幾個套件,經過測試之後,huysentruitw/SapNwRfc 這一個套件,它的使用方式我比較喜歡,而且可以支援強型別的 Model ,使用上會比較順手,另外也需要將程式部署到 App Service 執行,因此也把可能會遇到的問題記錄一下。 

實做

環境設定

套件是建立在官方 SAP NetWeaver RFC Library 7.50 SDK C++ 之上,所以需要先到 SAP 官方下載相關檔案,這邊就不方便直接提供檔案了。

下載之後解壓縮之後到 nwrfcsdk\lib 路徑底下會有一些 DLL 檔案,需要將 sapnwrfc.dllicudt50.dllicuin50.dllicuuc50.dll 這四個檔案複製到系統 PATH 目錄內,或是之後複製到程式輸出目錄底下。

實做說明

範例程式是 .NET 6 主控台應用程式專案,首先透過 NuGet 新增 SAPNwRfc 套件。

再來就來實做呼叫 SAP 內建的 Echo 的函數 STFC_STRUCTURE。再來先新增三個 Model 來作為輸入和輸出使用,可以看到我們自定義的類別加上 SapName 這一個 Attrubute,這樣就可以再送出和接收時候對應的到了,或是直接把名稱定義成和 SAP 的一樣,但是這樣可能會不符合自己專案命名規則,所以我會習慣用 Attrubute 來定義,也可以加上其它非 SAP 結構的欄位,這時候只需要加上 SapIgnore 這一個 Attrubute 就可以了。

/// <summary>
/// Echo Demo Input
/// </summary>
internal class EchoDemoInput
{
    /// <summary>
    /// RFC Table
    /// </summary>
    [SapName("RFCTABLE")]
    public EchoDemoItem[] RFCTable { get; set; }
}
/// <summary>
/// Echo Demo Item
/// </summary>
internal class EchoDemoItem
{
    /// <summary>
    /// RfcFloat
    /// </summary>
    [SapName("RFCFLOAT")]
    public double RfcFloat { get; set; }
    /// <summary>
    /// RfcChar1
    /// </summary>
    [SapName("RFCCHAR1")]
    public string RfcChar1 { get; set; }
    /// <summary>
    /// RfcChar2
    /// </summary>
    [SapName("RFCCHAR2")]
    public string RfcChar2 { get; set; }
    /// <summary>
    /// RfcChar4
    /// </summary>
    [SapName("RFCCHAR4")]
    public string RfcChar4 { get; set; }
    /// <summary>
    /// RfcHEX3
    /// </summary>
    [SapName("RFCHEX3")]
    public byte[] RfcHEX3 { get; set; }
    /// <summary>
    /// RfcDate
    /// </summary>
    [SapName("RFCDATE")]
    public DateTime? RfcDate { get; set; }
    /// <summary>
    /// RfcData1
    /// </summary>
    [SapName("RFCDATA1")]
    public string RfcData1 { get; set; }
}
/// <summary>
/// Echo Demo Output
/// </summary>
internal class EchoDemoOutput
{
    /// <summary>
    /// Response Text
    /// </summary>
    [SapName("RESPTEXT")]
    public string ResponseText { get; set; }
    /// <summary>
    /// RFCTable
    /// </summary>
    [SapName("RFCTABLE")]
    public EchoDemoItem[] RFCTable { get; set; }
}

再來新增呼叫 Echo Demo 的程式,透過 CreateFunction 來建立呼叫的程式,然後傳入資料,因範例也會回傳資料,因此將回傳的類別也加上,到時候執行完成之後就會 Mapping 資料到類別上了。

internal class SAPService
{
    private SapConnection sapConnection;

    public SAPService(string connectionString)
    {
        sapConnection = new SapConnection(connectionString);
        sapConnection.Connect();
    }

    /// <summary>
    /// 呼叫 Echo Demo
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="sapFunction">SAP Function</param>
    /// <returns></returns>
    public EchoDemoOutput EchoDemo(EchoDemoInput input)
    {
        using var sapFunctionClient = sapConnection.CreateFunction("STFC_STRUCTURE");
        return sapFunctionClient.Invoke<EchoDemoOutput>(input);
    }
}

再來就可以在主程式裡面呼叫來測試了,不過先來新增一個產生假資料的程式。

/// <summary>
/// 產生假資料
/// </summary>
/// <returns></returns>
EchoDemoInput GenEchoDemoItems()
{
    var demoInput = new EchoDemoInput();
    var items = new List<EchoDemoItem>();

    for (int i = 0; i < 10; i++)
    {
        var item = new EchoDemoItem()
        {
            RfcFloat = 12345.6789,
            RfcChar1 = "AnYun",
            RfcChar2 = "AB",
            RfcChar4 = "NCO3",
            RfcHEX3 = new byte[] { 0x41, 0x42, 0x43 },
            RfcDate = DateTime.Today,
            RfcData1 = "Hello World"
        };

        items.Add(item);
    }
    demoInput.RFCTable = items.ToArray();

    return demoInput;
}

最後呼叫上就很簡單了,連線字串的格式可以參考底下的範例,自行調整輸入相關參數。

// AppServerHost=MY_SERVER_HOST; SystemNumber=00; User=MY_SAP_USER; Password=SECRET; Client=100; Language=EN; PoolSize=5; Trace=8
var connectionString = "";
var sapService = new SAPService(connectionString);
var input = GenEchoDemoItems();
var result = sapService.EchoDemo(input);

如果有正常回應的話,可以看到底下的結果,在我們輸入的資料後面會被加上一筆記錄並且回傳,這樣就完成的程式串接了。

App Service 執行注意事項

因為是命令列程式,所以是上傳到 App Service 作為 WebJob 來執行,在部署的時候有一些點需要注意的,分別說明如下:

1.需手動上傳 SAP 相關 DLL,因為不是直接給 .NET 使用的函示庫,所以沒辦法加入到專案,所以部署時候需要手動上傳檔案,可以透過 Kudu 來拖曳檔案來上傳檔案到執行目錄底下。

2. 需將檔案編譯成 win-x64 格式,不然執行上會失敗,

透過 Virtual Studio 部署時候將目標執行階段設定成 win-x64。

結論

簡單的介紹如何在 .NET Core 串接並呼叫 SAP 的 Function,在實做過程遇到的一些雷,以及實做過程做個記錄,以防未來的自己遇到的時候又忘記要怎麼處理了,希望對有需要的朋友也有一點幫助。

附上完成程式碼 GitHub

參考資料