{"record":{"id":"3585c69afeeef18b","repo":"JeffreySu/WeiXinMPSDK","slug":"brandmembercardapis","errorCode":null,"errorMessage":"文件名不能为空。","messagePattern":"文件名不能为空。","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/Apis/BrandMemberCard/BrandMemberCardApis.cs","lineNumber":362,"sourceCode":"        /// <returns>永久有效的媒体文件 URL。</returns>\n        public Task<BrandMemberCardImageUploadResultJson> UploadMemberImageAsync(\n            string fileName, Stream fileStream,\n            CancellationToken cancellationToken,\n            int timeOut = Config.TIME_OUT)\n        {\n            ValidateBrandMemberImageFileName(fileName);\n            const string path = \"brand/card-member/media/image-upload\";\n            return _request\n                .RequestMultipartWithFilenameAndFileDigestAsync<\n                    BrandMemberCardImageUploadResultJson>(GetUrl(path),\n                    fileName, fileStream, cancellationToken, timeOut);\n        }\n\n        private static void ValidateBrandMemberImageFileName(string fileName)\n        {\n            if (string.IsNullOrWhiteSpace(fileName))\n            {\n                throw new ArgumentException(\"文件名不能为空。\",\n                    nameof(fileName));\n            }\n\n            switch (Path.GetExtension(fileName)?.ToLowerInvariant())\n            {\n                case \".jpg\":\n                case \".jpeg\":\n                case \".bmp\":\n                case \".png\":\n                    return;\n                default:\n                    throw new ArgumentException(\n                        \"商家名片会员图片仅支持 JPG、JPEG、BMP 或 PNG。\",\n                        nameof(fileName));\n            }\n        }\n\n        private Task<T> PostAsync<T>(string path, object data, int timeOut)","sourceCodeStart":344,"sourceCodeEnd":380,"githubUrl":"https://github.com/JeffreySu/WeiXinMPSDK/blob/be573f6f94bdbf718dd5f6cdecb137fbc7ff651e/src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/Apis/BrandMemberCard/BrandMemberCardApis.cs#L344-L380","documentation":"UploadMemberImageAsync validates the image file name via ValidateBrandMemberImageFileName, which throws ArgumentException when the fileName is null, empty, or whitespace. The file name is needed both to derive the extension and to build the upload metadata for the brand member card image API.","triggerScenarios":"Calling UploadMemberImageAsync with fileName = null, \"\", or \"   \", or deriving the file name from an upload whose original name was lost.","commonSituations":"Browser uploads stripped of filename metadata; using stream-only upload helpers and forgetting to pass a name; variables populated from config keys that are empty.","solutions":["Pass a non-empty file name including its extension (e.g. \"member.png\").","If only a byte stream is available, supply a synthetic name with a valid extension like \"image.jpg\".","Add a null/empty check in your upload pipeline before invoking the API."],"exampleFix":"// before\nawait apis.UploadMemberImageAsync(brandId, fileBytes, fileName: null);\n// after\nawait apis.UploadMemberImageAsync(brandId, fileBytes, fileName: \"member-avatar.png\");","handlingStrategy":"validation","validationCode":"if (string.IsNullOrWhiteSpace(fileName))\n    throw new ArgumentException(\"fileName is required for member image upload.\");","typeGuard":"bool hasFileName = !string.IsNullOrWhiteSpace(fileName);","tryCatchPattern":"try { await apis.UploadMemberImageAsync(brandId, bytes, fileName); }\ncatch (ArgumentException ex) { logger.Warn(ex, \"Missing image file name\"); throw new UserInputException(\"Please select a named image file.\"); }","preventionTips":["Always derive fileName from the original upload and preserve it end-to-end","Fall back to a synthetic name with a valid extension when metadata is lost","Check file-name inputs at the UI/form layer"],"tags":["argument-validation","empty-value","image-upload"],"backgroundTag":"empty-required-field","analyzedSha":"be573f6f94bdbf718dd5f6cdecb137fbc7ff651e","analyzedAt":"2026-09-12T10:01:50.733Z","contentChangedAt":"2026-09-12T10:01:50.733Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}