简介
该博文记录了一些平时在工作中遇到的问题及解决办法,某些问题有解决办法,某些问题暂时没有解决办法,如果有大神知道的,请多多指点。
如果某些问题有更好的解决办法,也请指教。
知识点
1、在一个方法中用泛型操作两个不同的类型(Type)。
难点:需要实现一个方法,进入参数一个泛型,返回信息一个泛型。但是一个方法中泛型只支持一种类型。
解决办法:将进入和返回放在一个类型中,用特性将进入参数和返回参数区分开。
2、微信三方登录,需要在PC桌面应用端+API服务实现。
难点:微信官网只提供了网页三方登录。桌面应用没有浏览器插件。
解决办法:如果要将二维码显示在桌面应用端,实现扫码功能,必须将微信三方网页登录整个流程分析清楚,再在服务端模拟微信扫码功能。
WEB流程:请求微信三方登录接口;微信端返回一个HTML页面,内部有二维码和一个心跳包(轮训查看扫码情况);当扫码成功,回调请求时给的回调地址。
C/S流程:请求微信三方登录接口;微信返回一个HTML页面,将该HTML页面直接在后端服务代码中拆解开来,把二维码信息返回给C/S端,用代码将心跳包逻辑
写出来,在服务中实现;当扫码成功以后,将扫码信息和客户微信信息放入缓存中;C/S端通过请求指定API接口获取扫码情况。
3、以Windows服务形式的WebApi服务实现类似于寄宿IIS的WebApi服务接口帮助网页。
难点:在Windows服务中没有不容易模拟GlobalConfiguration全局配置。而且WebApi本身的帮助网页也不能将返回实体的JSON例子完全显示出来
(如果实体是其他类库的,就无法找到);POST请求的形式,无法显示具体请求参数信息;返回的不是自定义实体,也无法显示返回信息。
解决办法:模拟WebApi本身的帮助网页功能,通过读取程序本身生成的XML文档+反射实现。
流程:读取XML文档,找出各个接口的基础信息(备注,请求方式,请求域名+地址);在接口代码注释中添加自定义注释(请求参数实体,返回参数实体);
用反射找到具体接口请求和返回信息,再一JSON形式表示出来。
4、byte[]转换成stream出现内存不足问题。
问题:将过大的byte[]一次性转换成stream并写入文件,会报内存不足问题。
解决办法:将一次转换写入,编程多次转换写入。
5、vs2012打开项目,运行时,提示ASP.net4.5未在web服务器上注册
解决办法:安装VS补丁,地址是补丁。
6、SQL Server 2012 自动增长列,值跳跃问题
相关资料:SQL Server 2012 Auto Identity Column Value Jump Issue
从 SQL Server 2012 版本开始, 当SQL Server 实例重启之后,表格的自动增长列的值会发生跳跃,而具体的跳跃值的大小是根据增长列的数据类型而定的。如果数据类型是 整型(int),那么跳跃值为 1000;如果数据类型为 长整型(bigint),那么跳跃值为 10000。从我们的项目来看,这种跳跃问题是不能被接受的,尤其是展示在客户端的时候。这个奇怪的问题只在 SQL Server 2012 及更高的版本中存在,SQL Server 2012之前版本不存在此问题。
解决方案
1. 使用序列 (Sequence)
首先,我们需要移除表格的自增列。然后创建一个不带缓存功能的序列,根据此序列插入数值。
CREATE SEQUENCE Id_Sequence
AS INT
START WITH 1
INCREMENT BY 1
MINVALUE 0
NO MAXVALUE
NO CACHE
insert into Table values(NEXT VALUE FOR Id_Sequence, 'xxx');
2. 为SQL Server 注册启动参数 -t272
打开SQL Server配置管理器。 选择 SQL Server 2012 实例,右键, 选择属性菜单。在弹出的窗口中找到启动参数,然后注册 -t272。 完成之后重启下图中的SQL Server(SQLSERVER2012), 之后进行bug重现的操作,验证问题是否已解决。
7、jQuery+Ajax无法实现跨域操作
问题原因:js为了安全性,启用了同源策略-只能访问与包含它的文档或脚本在同一域名下的内容。
解决办法:在Web.config中的<system.webServer>节点下添加允许跨域访问的节点,代码如下:
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>
8、调用方法体中用了函数(强制转换成Int32)-编码不规范问题。
问题点:在项目中调用一个方法:Function(parOne, Convert.ToInt32(priceStr), parThree);,直接在方法体中用Convert.Int32将1.00强制转换发生错误。报的错误:输入字符串的格式不正确。这个问题一看就知道是转化出错了,但是可以直接去错误点看。但是当Function内部无法调试,且逻辑很复杂的时候,就不一定直接定位到Function的调用上了(没几个人首先去看调用方法的时候出错没有)。
解决办法:先转换成double,再(int)转换。其实真真的问题在于编码不规范。在调用方法时,直接传递参数,不在调用时做函数处理。
9、C#操作MongoDB重复插入数据问题。
据我查找资料。C#中不支持MongoDB有同时判断数据库中是否含有记录,再做操作的事务操作功能。
问题点:在查询是否存在再做操作这两个操作中用了一般的单列模式(没有加锁)。结果在IIS重新编译后,将编译期间存到缓存队列的请求该操作的相同请求一起处理,造成多线程并发,出现多个实例。
解决办法:在单例中用私有静态Lock。
if (instance == null)
{
lock (locker)
{
//如果类的实例不存在则创建,否则直接返回
if(instance == null)
{
instance = new singleClass ();
}
}
}
10、C#操作MongoDB增加自增列。
问题点:MongoDB本身为分布式开发设计的,自身是没有带自增列功能的,C# MongoDB.Driver 也没有这种功能。
解决办法:利用MongoDB.Driver中的FindOneAndUpdate+InsertData实现。
实现:
1、先在MongoDB数据库目标表手动添加一行数据,其中包括特殊行标记字段(tableMark,值为:"TableMark",其他非标记数据行,值为空)和当前表总行数(reg)。
2、实现代码如下。
11、 Task.Run(() => });中使用HttpContext失败。
问题点:Task.Run(() => });中使用HttpContext失败。
解决办法:因为Task.Run另外开启线程,在主线程中的HttpContext不会被带入Task.Run中。只有将使用HttpContext的方法放在Task.Run外面,将结果传入Task.Run中操作。