{"record":{"id":"b7a3e32e3e8f9647","repo":"JeffreySu/WeiXinMPSDK","slug":"productcouponapis","errorCode":null,"errorMessage":"文件名不能为空。","messagePattern":"文件名不能为空。","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/Apis/ProductCoupon/ProductCouponApis.cs","lineNumber":809,"sourceCode":"                              Escape(query[index + 1]));\n                }\n            }\n\n            return parts.Count == 0\n                ? path\n                : $\"{path}?{string.Join(\"&\", parts)}\";\n        }\n\n        private static string Escape(string value)\n        {\n            return Uri.EscapeDataString(value ?? string.Empty);\n        }\n\n        private static void ValidateImageFileName(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}","sourceCodeStart":791,"sourceCodeEnd":827,"githubUrl":"https://github.com/JeffreySu/WeiXinMPSDK/blob/be573f6f94bdbf718dd5f6cdecb137fbc7ff651e/src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/Apis/ProductCoupon/ProductCouponApis.cs#L791-L827","documentation":"ValidateImageFileName (ProductCouponApis.cs:809), used by UploadImageAsync, guards the WeChat product-coupon image upload API: the file name must be non-empty (and its extension must be jpg/png/jpeg etc.). An empty/whitespace fileName throws ArgumentException naming the parameter before any HTTP request is made.","triggerScenarios":"Calling UploadImageAsync with a null, empty, or whitespace-only fileName string, typically because the path variable was never assigned or an upload form field was missing.","commonSituations":"Reading a file name from user input/config that came back empty; passing Path.GetFileName on a path that had no filename; upload pipeline dropping the file name before reaching the API call.","solutions":["Ensure a non-empty file path/name is passed to UploadImageAsync and check it before calling","Verify the file exists and Path.GetFileName(path) yields a value with a supported extension (.jpg/.png/.jpeg)","Add an upfront guard in your upload flow to reject empty file names with a friendly error"],"exampleFix":"// before\nawait api.UploadImageAsync(fileName); // fileName == \"\"\n\n// after\nif (string.IsNullOrWhiteSpace(fileName))\n    throw new InvalidOperationException(\"Image file name must be provided\");\nawait api.UploadImageAsync(fileName);","handlingStrategy":"validation","validationCode":"if (string.IsNullOrWhiteSpace(fileName))\n    throw new ArgumentException(\"Image file name is required\", nameof(fileName));\nvar ext = Path.GetExtension(fileName)?.ToLowerInvariant();\nif (ext is not (\".jpg\" or \".jpeg\" or \".png\"))\n    throw new ArgumentException($\"Unsupported image extension: {ext}\");","typeGuard":"bool ValidImageName(string? fileName) =>\n    !string.IsNullOrWhiteSpace(fileName) &&\n    new[] { \".jpg\", \".jpeg\", \".png\" }.Contains(Path.GetExtension(fileName)?.ToLowerInvariant());","tryCatchPattern":"try { await api.UploadImageAsync(fileName); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"文件名不能为空\"))\n{ logger.LogError(ex, \"Empty file name passed to coupon image upload\"); throw; }","preventionTips":["Validate file name/extension at the UI or API boundary before invoking the SDK","Ensure file pickers always supply a name; never forward raw empty config values","Run Path.GetFileName on full paths to guarantee a non-empty name"],"tags":["tenpay","product-coupon","upload","validation"],"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"}