JeffreySu/WeiXinMPSDK · error · ArgumentNullException

ArgumentNullException (value is null)

Error message

ArgumentNullException (value is null)

What it means

Utf8NativeString wraps a managed string into a null-terminated UTF-8 buffer for native calls, and its constructor rejects null input with ArgumentNullException(nameof(value)). You must pass an actual string (use string.Empty if you mean an empty value).

Solutions

  1. Null-check config values before constructing Utf8NativeString.
  2. Coalesce to string.Empty only if the SDK accepts empty values; otherwise fail fast with a clear config error.
  3. Load configuration before initializing the finance API (fail at startup, not per call).

Example fix

// before
using var corpId = new Utf8NativeString(config.CorpId); // ArgumentNullException if null
// after
if (string.IsNullOrEmpty(config.CorpId))
    throw new InvalidOperationException("CorpId is not configured");
using var corpId = new Utf8NativeString(config.CorpId);
Defensive patterns

Strategy: validation

Validate before calling

if (string.IsNullOrEmpty(config.CorpId) || string.IsNullOrEmpty(config.Secret))
    throw new InvalidOperationException("CorpId/Secret not configured for Finance SDK");

Type guard

static bool HasText(string s) => !string.IsNullOrWhiteSpace(s);

Try / catch

try { using var s = new Utf8NativeString(value); }
catch (ArgumentNullException ex) { logger.LogError(ex, "Null native string argument"); throw new InvalidOperationException("Config value missing", ex); }

Prevention

When it happens

Trigger: Passing a null string to new Utf8NativeString(value) — e.g. corpId or secret variables that were null because config values were not loaded before constructing native API arguments.

Common situations: Missing appsettings entries for CorpId/Secret so the variable is null at call time; refactoring that renamed a config property and left the argument null.

Related errors


AI-assisted analysis of JeffreySu/WeiXinMPSDK@be573f6f94 (2026-09-12). Data as JSON: /api/errors/2494ea94f5640d3c. Report an issue: GitHub.

Appendix: source

Thrown at src/Senparc.Weixin.Work/Senparc.Weixin.Work/AdvancedAPIs/MsgAudit/MsgAuditFinanceNativeApi.cs:564

        }
    }

    /// <summary>
    /// 将托管字符串转换为以空字符结尾的 UTF-8 原生缓冲区,并在释放时清零。
    /// </summary>
    internal sealed class Utf8NativeString : IDisposable
    {
        private readonly int _length;

        /// <summary>
        /// 创建 UTF-8 原生字符串。
        /// </summary>
        /// <param name="value">待转换的托管字符串。</param>
        public Utf8NativeString(string value)
        {
            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }

            var bytes = Encoding.UTF8.GetBytes(value);
            _length = bytes.Length + 1;
            Pointer = Marshal.AllocHGlobal(_length);
            try
            {
                if (bytes.Length > 0)
                {
                    Marshal.Copy(bytes, 0, Pointer, bytes.Length);
                }

                Marshal.WriteByte(Pointer, bytes.Length, 0);
            }
            catch
            {
                Marshal.FreeHGlobal(Pointer);
                Pointer = IntPtr.Zero;

View on GitHub (pinned to be573f6f94)