วันนี้เจอเคสแปลกครับ น้องที่อยู่ Onsite แจ้งว่าตัว VSTO Office Add-ins ที่ Run บน Windows 7 เจอ Error ไม่สามารถ Deserialize JSON ได้ครับ สำหรับผมเอ๊ะ มันมีอะไรผิดไปหว่า จำได้ว่าตอน Migrate .NET6 ตัว
- Main Project ย้ายไป .NET6 หมด
- VSTO Office Add-ins ยังต้องคงไว้ .NET4.8.1 เนื่องจาก Microsoft ยกเลิกการ Support ไปแล้ว โดยใช้ให้ตัว Office Web Add-ins. ครับ กลับมาที่ VSTO เรากันก่อน โดย 2 App ได้แก่ ตัว Main Project + Office VSTO มันต้องคุยกัน และมีปรับแก้ไขไป ดังนี้
- เดิม TCP + BinaryFormatter ซึ่งแจ้งตัว BinaryFormatter ผมเอาออกไป เพราะ .NET5.0 เอาออกไปแล้ว เนื่องจาก Security Issue โดยใช้ JSON แทน BinaryFormatter
- ใหม่ TCP + JSON ครับ
ตัว VSTO Office AddIns ผมได้ทดสอบบน Windows 8.1 / 10 / 11 เรียบร้อยตาม Environment ที่ลูกค้าแจ้งสามารถทำงานได้ครับ แต่ทว่าดันมีเคสเกิดขึ้นกับ Windows 7 ซะงั้น ตามรูปเลย
ให้น้องอยู่ Onsite ลองเอา Error Log มาดู มัน Deserialize JSON ไม่ได้จริงๆ
วิเคราะห์เคส
เนื่องจากการสื่อสารผ่านตัว TCP ดังนั้นจุดที่สงสัยเลย Message ดิบ ของ Windows 7 / Windows 10 มันต่างกันยังไงนะ ปรากฏว่า Windows 7 ตัว JSON แหว่งครับ
- Windows7
{ "UserProperties":{} ,"Username":"chatri" ,"LicenseRole":"BACK" ,"LoginTime":"2023-05-23T17:16:54.724221+07:00" ,"Privileges":[1000201,1000202,1000203,1000204,1000205,1000206,1000207,1000208,1000209,1000301,1000302,1000303 ....... ,1107503,1107504,1107505,1107506,1107507,1107508,1107509,1107801 ,1107802,1107803,1107804,1107805,1107806,1107807,1107808,1107809 ,1107901,110 << มันแหว่ง
- Windows10 - JSON มาครบครับ
{ "UserProperties":{} ,"Username":"chatri" ,"LicenseRole":"BACK" ,"LoginTime":"2023-05-23T16:43:50.3663268+07:00" ,"Privileges":[ 1000201,1000202,1000203,1000204,1000205,1000206,1000207,1000208,1000209,1000301,1000302,1000303 ....... ,2800101,1512301,1512302,1512303,1512304,1512305,1512306,1512307,1512308,1512309,1512311,1512314,1512201,1512207,1512101,1512001 ] ,"IsAuthenticated":true ,"Id":2508 ,"ErrorResults":[] }
เหมือนจะมีแสงสว่างเลย สงสัยตรง TcpClient.ReceiveTimeout / TcpClient.ReceiveBufferSize ครับ
- ลองไปปรับเวลาตรง TcpClient.ReceiveTimeout ก่อน ปรากฏว่าไม่ใช่ ปัญหาเดิมยังอยู่ครับ
- อีกจุด TcpClient.ReceiveBufferSize ลองให้มัน WriteLog ออกมาเจอเคสแปลกครับ
- Doc ของ MS บอกว่า 8,192 bytes
- Windows 7 ได้ 8,192 bytes
- Windows 10 ได้ 65,536 bytes
Solution
- ปรับ Code จากเดิมที่ใช้ Const TcpClient.ReceiveBufferSize มาเป็นกำหนด Config โดยให้ App มันอ่านค่า โดย Default ค่าเป็น 65,536
- จุดสังเกตุ Doc ของ MS บอกว่าเป็น 8,192 bytes แต่ทำไมพฤติกรรมของแต่ละ OS ไม่เหมือนกัน
อย่างน้อยปิดเคสได้ไปอีกเคสครับ
Reference
- TcpClient.ReceiveBufferSize Property (System.Net.Sockets) | Microsoft Learn
- c# - TcpClient always got ReceiveBufferSize = 65536 on Windows 8.1 - Stack Overflow
- Breaking change: BinaryFormatter serialization methods are obsolete and prohibited in ASP.NET apps - .NET | Microsoft Learn
Discover more from naiwaen@DebuggingSoft
Subscribe to get the latest posts sent to your email.