如何修改ASP.NET Core二维码生成接口以保存二维码为本地图片
问题:二维码保存为图片文件的实现是否正确?
需求:将生成的二维码保存为图片文件。
原有代码:
[HttpGet("GenerateQrCode")] public ActionResult<string> GenerateQrCode(string sellername, string vatregistration, string timestamp, string invoiceamount, string vatamoun) { string ltr = ((char)0x200E).ToString(); var seller = ConvertTLV("1", sellername); var vatno = ConvertTLV("2", vatregistration); var time = ConvertTLV("3", timestamp); var invamt = ConvertTLV("4", invoiceamount); var vatamt = ConvertTLV("5", vatamoun); var result = seller.Concat(vatno).Concat(time).Concat(invamt).Concat(vatamt).ToArray(); return Ok(new { QrCode = Convert.ToBase64String(result) }) ; }
尝试的修改后代码:
[HttpGet("GenerateQrCode")] public ActionResult<string> GenerateQrCode(string sellername, string vatregistration, string timestamp, string invoiceamount, string vatamoun) { string ltr = ((char)0x200E).ToString(); var seller = ConvertTLV("1", sellername); var vatno = ConvertTLV("2", vatregistration); var time = ConvertTLV("3", timestamp); var invamt = ConvertTLV("4", invoiceamount); var vatamt = ConvertTLV("5", vatamoun); var result = seller.Concat(vatno).Concat(time).Concat(invamt).Concat(vatamt).ToArray(); string QrCode = Convert.ToBase64String(result); byte[] qrCodeBytes = Convert.FromBase64String(QrCode); string filePath = "E:/qrcode.png"; using (var stream = new MemoryStream(qrCodeBytes)) { stream.Position = 0; // Set the position to the beginning of the stream try { Image qrCodeImage = Image.FromStream(stream); qrCodeImage.Save(filePath, ImageFormat.Png); } catch (ArgumentException ex) { // Handle the "Parameter is not valid" error Console.WriteLine("Error: " + ex.Message); } } return Ok(new { qrcode = filePath }) ; }
咨询:该修改方案是否正确?若存在问题,请指出并提供正确的实现方式。
问题分析与正确实现
你的修改方案完全错误,核心逻辑存在致命误解:
- 原有代码中的
result是TLV编码后的业务原始数据,并非二维码图片的字节流。你直接把它转成Base64再转回字节流,本质还是原始业务数据,根本不是图片格式,所以Image.FromStream必然抛出参数无效的异常。 - 你跳过了生成二维码图片的核心步骤,直接把业务数据当成图片处理,逻辑完全颠倒。
正确实现方案
要完成需求,需先将TLV编码后的原始数据生成二维码图片,再保存到文件。实现依赖二维码生成库,这里用最常用的ZXing.Net。
1. 安装依赖库
通过NuGet安装:
Install-Package ZXing.Net
或.NET CLI:
dotnet add package ZXing.Net
如果是.NET Core/.NET 5+,还需安装System.Drawing.Common用于图片处理:
Install-Package System.Drawing.Common
2. 正确代码实现
using ZXing; using ZXing.QrCode; using System.Drawing; using System.Drawing.Imaging; [HttpGet("GenerateQrCode")] public ActionResult<string> GenerateQrCode(string sellername, string vatregistration, string timestamp, string invoiceamount, string vatamoun) { string ltr = ((char)0x200E).ToString(); var seller = ConvertTLV("1", sellername); var vatno = ConvertTLV("2", vatregistration); var time = ConvertTLV("3", timestamp); var invamt = ConvertTLV("4", invoiceamount); var vatamt = ConvertTLV("5", vatamoun); var result = seller.Concat(vatno).Concat(time).Concat(invamt).Concat(vatamt).ToArray(); // 1. 配置二维码生成参数 var writer = new BarcodeWriterPixelData { Format = BarcodeFormat.QR_CODE, Options = new QrCodeEncodingOptions { Width = 300, Height = 300, Margin = 1, CharacterSet = "UTF-8" } }; // 2. 生成二维码像素数据 var pixelData = writer.Write(result); // 3. 将像素数据转换为Bitmap并保存 string filePath = "E:/qrcode.png"; using (var bitmap = new Bitmap(pixelData.Width, pixelData.Height)) { var bitmapData = bitmap.LockBits( new Rectangle(0, 0, pixelData.Width, pixelData.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppRgb); System.Runtime.InteropServices.Marshal.Copy(pixelData.Pixels, 0, bitmapData.Scan0, pixelData.Pixels.Length); bitmap.UnlockBits(bitmapData); bitmap.Save(filePath, ImageFormat.Png); } return Ok(new { qrcodeFilePath = filePath }); }
补充注意事项
- 非Windows平台(如Linux/macOS)使用
System.Drawing.Common可能有兼容性问题,可改用ZXing.Net.Bindings.ImageSharp替代,避免依赖System.Drawing。 - 确保应用程序有目标路径的写入权限,建议使用应用程序私有目录(如
wwwroot/qrcodes/)而非系统根目录。 - 需保证
ConvertTLV方法正确实现TLV编码,否则二维码内容会无效。
内容的提问来源于stack exchange,提问作者asmaa hamed
相关产品推荐
相关产品推荐

