JeffreySu/WeiXinMPSDK · error · ArgumentNullException
fileStream
Error message
fileStream
What it means
RequestMultipartCoreAsync is the shared implementation behind the four public multipart upload methods (RequestMultipartAsync and its with-max-size / file-digest / filename-and-digest variants). It validates the fileStream argument and throws ArgumentNullException when the uploaded content stream is null, because a multipart file upload cannot be constructed without stream content to write into the multipart body. The offending input is the fileStream parameter passed by one of the public wrappers.
Solutions
- Open the file stream before the call and assert it is non-null and readable (stream.CanRead)
- Check the file exists with File.Exists before opening to give a better error
- Ensure the stream is not disposed/closed before the async upload completes
Example fix
// before using FileStream fs = fileExists ? File.OpenRead(path) : null; await apiRequest.RequestMultipartAsync(url, fileName, fs); // after if (!File.Exists(path)) throw new FileNotFoundException(path); using var fs = File.OpenRead(path); await apiRequest.RequestMultipartAsync(url, fileName, fs);
Defensive patterns
Strategy: validation
Validate before calling
if (fileStream == null || !fileStream.CanRead)
throw new InvalidOperationException("文件流不可读,请先打开文件"); Try / catch
try { await apiRequest.RequestMultipartAsync(url, fileName, fileStream); }
catch (ArgumentNullException ex) when (ex.ParamName == "fileStream") { log.Error("文件流为空", ex); throw; } Prevention
- Check File.Exists before File.OpenRead; wrap open in try-catch for FileNotFoundException
- Keep the stream open until the async upload completes (avoid premature using/dispose)
- Accept Stream parameters in your own layer and fail fast on null
When it happens
Trigger: Passing a null Stream — commonly File.OpenRead on a nonexistent path assigned before the call and swallowed, or a stream from an async open that returned null.
Common situations: File missing at runtime (wrong working directory), stream already disposed and nulled, or conditional file-open logic that skipped opening.
Related errors
AI-assisted analysis of JeffreySu/WeiXinMPSDK@be573f6f94 (2026-09-12).
Data as JSON: /api/errors/4e8a4fbef15a4fdb.
Report an issue: GitHub.
Appendix: source
Thrown at src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/HttpHandlers/TenPayApiRequest.cs:381
{
return RequestMultipartCoreAsync(url, fileName, fileStream,
cancellationToken,
MultipartMetaFieldStyle.FilenameAndFileDigest, timeOut,
checkSign, createDefaultInstance, maxFileBytes);
}
private async Task<T> RequestMultipartCoreAsync<T>(string url, string fileName,
Stream fileStream, CancellationToken cancellationToken,
MultipartMetaFieldStyle metaFieldStyle, int timeOut, bool checkSign,
Func<T> createDefaultInstance, int? maxFileBytes = null)
where T : ReturnJsonBase, new()
{
if (string.IsNullOrWhiteSpace(fileName))
{
throw new ArgumentException("文件名不能为空。", nameof(fileName));
}
_ = fileStream ?? throw new ArgumentNullException(nameof(fileStream));
if (timeOut <= 0 && timeOut != Timeout.Infinite)
{
throw new ArgumentOutOfRangeException(nameof(timeOut), "超时时间必须大于 0,或使用 Timeout.Infinite。 ");
}
if (maxFileBytes.HasValue && maxFileBytes.Value <= 0)
{
throw new ArgumentOutOfRangeException(nameof(maxFileBytes),
"文件大小上限必须大于 0。");
}
if (maxFileBytes.HasValue && fileStream.CanSeek &&
fileStream.Length - fileStream.Position > maxFileBytes.Value)
{
throw new InvalidDataException(
$"上传文件超过允许上限 {maxFileBytes.Value} 字节。");
}
T result = null;
tryView on GitHub (pinned to be573f6f94)