最近那些事儿……
为了不耽误大家的时间,这里首先说一下下边文章中主要涉及的技术问题,如果有兴趣,大家可以一起研究一下,如果不喜欢,请绕道。写得不妥的地方,也希望大家指正。
本文主要说三个问题:
一、VS中跨工程调试,从一个工程进入另一个工程;
二、动态生成二维码和一维条形码;
三、前台页面直接访问图片流文件。
老规矩,先来点题外话。最近在园子里闲逛的时候,发现很多人都聊到了加班这个话题。其中有一哥们儿说是在京东,然后每天按时上下班,无不良记录,一个月后居然以工作不积极给开了……说到这里很多人就得有想法了,凭什么啊?说到程序员加班,似乎永远是个谈不完的话题,好像程序员就是为加班而生的。而这其中的辛酸血泪,也只有我们自己才知道。从去年进入公司以来,除了特殊情况(节假日,公司聚会),从来未按时下过班,大家都习惯磨磨蹭蹭,没事儿也在那儿耗着。我也问过比我先来的同事,为什么下班了还不走,原因很简单,上边的人都没走……
最近加班更是频繁,周一到周四住在公司,每天回寝室都是下半夜。其中的苦楚,说不清,道不明。我想说的是,我们一起,按时下班吧。工作和生活需要分开!
——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
一、跨工程调试
之前工作时发现要将项目中一部分的功能加以改造移动到另外一个项目去,本着DRY的原则,决定将项目生成一下,然后直接把dll复制过去。当复制过去直接使用时,发现程序报了空指针异常。而检查了一遍程也未发现有任何地方会导致空指针,唯一的办法就是打断点来调试一下,可是由于是引用的dll,所以没办法直接打断点,只能通过其他的方式。好在我有dll的源码,如何调试只是方法的问题了。这里说的跨工程调试,是指调试在不同的工程中的源代码。在同一个工程不同项目的代码是可以直接调试的。下面简单的介绍一下如何跨工程进行调试。
首先,找到需要调试的CS文件,然后将文件直接拖到正在运行的工程窗口中,将断点打在合适的位置上。再从原工程中找到此cs所在的项目的pdb文件,将pdb文件和dll一同复制到现工程的bin目录下,然后直接F5,接着,奇迹就发生了。
二、生成二维码和一维条形码
随着微信的兴起,二维码应用得越来越广泛。之前我们有个卖水果的客户说是要将二维码贴在水果上,通过手机一扫就能知道水果的产地,生长环境等信息。网上也有很多生成二维码的工具,但是希望大家慎用,有些会把您填写的信息秘密发回服务器,当然了,大多数还是可以用的。
文中提到的生成二维码和一维条形码,是通过开源的项目Zxing来实现的,其Github地址:https://github.com/zxing/zxing/,这是一个开源的项目,可以生成各种码。因为之前用了二维码和条形码,所以这里简单的说一下。
生成二维码和一维码只有细微的差别,体现在程序里相当于使用了不同类型的枚举。下面直接上代码:
在这里做这个示例用的是最传统的Web程序,直接添加了一个一般处理程序来处理这个生成二维码和一维条形码的逻辑。
首先通过context上下文获取传过来的一些参数:
string content = context.Request.QueryString["content"]; if (string.IsNullOrWhiteSpace(content)) return; content = HttpUtility.UrlDecode(content); string level = context.Request.QueryString["level"]; level = string.IsNullOrWhiteSpace(level) ? "M" : level.ToUpper(); string format = context.Request.QueryString["format"]; format = string.IsNullOrWhiteSpace(format) ? "png" : format.ToLower(); int margin = Convert.ToInt32(context.Request.QueryString["margin"]); int size = Convert.ToInt32(context.Request.QueryString["size"]);
然后通过前台传过来的参数生成相应的条码类型,这里仅仅只是生成了一维码和二维码,别的类似:
ErrorCorrectionLevel errorCorrectionLevel; ImageFormat imgFormat; BarcodeFormat barcodeFormat = GetImageFormat(context.Request.QueryString["mod"]); #region 获取生成图片类型 private static BarcodeFormat GetImageFormat(string mod) { switch (mod) { case "QR_CODE": return BarcodeFormat.QR_CODE; case "CODE_128": return BarcodeFormat.CODE_128; default: return BarcodeFormat.CODE_128; } } #endregion
接着,再初始化一些参数:
#region ErrorCorrectionLevel switch (level) { case "L": errorCorrectionLevel = ErrorCorrectionLevel.L; break; case "M": errorCorrectionLevel = ErrorCorrectionLevel.M; break; case "Q": errorCorrectionLevel = ErrorCorrectionLevel.Q; break; case "H": errorCorrectionLevel = ErrorCorrectionLevel.H; break; default: errorCorrectionLevel = ErrorCorrectionLevel.M; break; } #endregion #region ImageFormat switch (format) { case "jpeg": imgFormat = ImageFormat.Jpeg; break; case "gif": imgFormat = ImageFormat.Gif; break; case "bmp": imgFormat = ImageFormat.Bmp; break; default: imgFormat = ImageFormat.Png; break; } #endregion EncodingOptions options = new QrCodeEncodingOptions { DisableECI = true, //禁用ECI编码段: use UTF-8 encoding and the ECI segment is omitted CharacterSet = "UTF-8", //使用UTF-8编码 Width = 200, //设置宽度 Height = 80, //设置高度 Margin = 20, //设置间隙 ErrorCorrection = errorCorrectionLevel,//容错等级 PureBarcode = false//底部显示内容 };
最后,直接生成二维码或一维码图片:
BarcodeWriter writer = new BarcodeWriter(); writer.Format = barcodeFormat; //采用QR编码 writer.Options = options; context.Response.Clear(); context.Response.ContentType = imgFormat.GetMimeType(); //设置输出流ContentType using (Bitmap image = writer.Write(content)) //输出二维码图像 { using (MemoryStream ms = new MemoryStream()) { image.Save(ms, imgFormat); ms.WriteTo(context.Response.OutputStream); } } context.Response.Output.Flush(); context.Response.End();
至此,生成一维码或二维码告一段落。
三、输出图片到前台
看完生成条码的童鞋会发现,最后是将流输出了,是的,这是为了直接将图片输出到前台。这样,可以根据实时的动态请求,将需要生成的一维码或者二维码直接输出到前台,而前台的页面也非常简单,只需写一个<image>标签,将src指向后台的一般处理程序即可。这样就能将内容输出到前台。如图:当然了,您也可以根据自己的需要,在二维码中间穿插上自己的一些Logo或者图片信息,由于本文重在抛砖引玉,所以这里就不细说了。