首页 > 技术文章 > 记我遇到过的奇葩问题

tianxue 2016-02-25 18:13 原文

1、与外部公司对接接口报500
我们提供WebService接口,结果对方老老是报500,总是说我们这边有问题,可是我们已经对接了很多个公司,都对接成功了,这个问题又没有人原因看,因为想到肯定是对方调用方式不对,我也不愿意看,但是扭不过测试和产品同学,最后没有办法,让对方把代码发过来,我挨个挨个跟他们改正确。首先访问的地址就不对,把方法加上,还有ContentType也没有设置正确,还有我们这边根本没有压缩,却以压缩的方式访问。这些都可以看接口文档啊。我也是醉了。
 
2、测试同学反映说他们发给业务同学的exe文件点开就是用VS打开的
最后发现,业务同学的电脑没有把文件的后缀展示出来,她点的那个.exe文件,其实后面还有一串.config,所以实际上是.exe.config,这是App.config文件编译后的。
 
3、数据库某个状态变成不正常的状态
为了处理这个问题,我从入库的时候开始查,发现入库的时候是正确的,然后查修改时间和入库时间的时间差,发现有差距,怀疑后面有程序改了。这下没有办法了,所有有可能的程序代码全都下下来,挨个挨个看,终于发现了,是有一个程序代码错了,状态改错了,改完了之后,外网观察那个状态在也没有出现了。这就是一个苦力活。
 
4、WebForm解决中文乱码的问题
这个代码也不是我写的,我记得当时写这个代码的同学问了我,是不是***消息都是英文的,我说是啊,然后他说中文会有点乱码的问题,如果没有中文就没有问题。后来他就回家了。到快要发布外网的时候,不知道怎么回事测试同学发现有中文乱码的情况, 当时我请了半天假,出去了,测试同学扭着我们组的同学改,结果他们改了半天,直到下午3点我回来的时候都没有解决,我回来的时候 ,就让我搭建什么环境,调式代码,我本来也开始这么干了,后来我就问是不是在***程序,他们说是,我说不用改,配置文件加节点,处理一下就可以了。在web.config中,有这样一个节点:
 <globalization requestEncoding="gb2312" responseEncoding="gb2312"/>
我记得我有一次也遇到这个问题,当时记得只要把这个编码改成 utf-8就可以了,但是不知道对其他文件有什么影响,于是就只针对具体页面配置了一下。
<location path="***/***.aspx">
<system.web>
<globalization fileEncoding="utf-8" requestEncoding="utf-8" responseEncoding="utf-8" culture="zh-CN"/>
</system.web>
</location>
加了这个配置文件之后,这个问题就解决了。其实我对WebForm一直不熟悉,都是度娘出来的。
 
5、外网服务报没有找到Get_XXX方法或者Set_XXX方法
当时我正在食堂吃放,研发同学看到我就说,你还没有走啊,我说是啊,他说:“那你吃完了,帮我看下问题。”,旁边的妹纸问我他是不是某个测试同学,我说不是他是研发同学,然后她问我,你们说的是不是***,我说是啊,她说:“你快去看问题,我帮你收拾”。然后我就飞快的跑过去看问题了,报的就是上面的错,于是跟研发同学说,你们这个dll不匹配,你看下你们是不是加了新字段,在别的服务没有丢进去。按照这个思路,果断解决问题。这个问题其实一点也不奇葩。
 
6、为什么WCF服务处理成功后,没有把状态改了
这个东西,我把代码牵下来看,怎么看都觉得是对的,其实里面的业务逻辑,我也看得头大,就想找做这个的人去看问题(之前看过一次,不了了之),结果她死活不干,还说我踢皮球,一怒之下,让测试同学跟我提服务器异常日志,测试同学提了两次,起码2个小时左右,因为运行时间有点差,本地日志太大了,压缩了好久,发了一个给我,却没有那一天的,后来我让他直接提那一天的日志给我,一看日志:System.InvalidCastException: Unable to cast object of type 'System.String' to type '***.*Result'.通过组件调用wcf服务,返回的类型不匹配,实际上wcf服务的处理已经完成。服务里面处理完成,但是去拿服务的结果就报错了,所以根本没有更新状态。解决办法就是把返回值类型改成string就可以了。又是一个隐藏很深的低级的错误。
 
7、连续创了十来个一模一样的订单
这个问题,我最初查到的时候,我以为是有人在爬我们网站。直到有人操作复现这个问题的时候,才发现是我们网站本身代码的问题。就个验证的地方,验证不通过会绑定一次跳过验证创单的提示。
老的代码是这样的:
$("#aaa").live("click", function () {
    // to create order
});
修改成这样就对了:
$("#aaa").off("click").on("click", function () {
// to create order
});
具体的原因我说不太清楚,就不说了。
 
8、Session是引用类型的
这个问题,我们经常遇到这样的坑,把一个对象存到session之后,又修改这个对象,然后Session中的值也变了。
 
9、注意处理异步调用里的异常,不然出了问题找不到
public void Test()
{
    try
    {
        // 一部分功能,同步处理

        // 有一部分异步处理
        Action<object> action = new Action<object>((obj) =>
        {
            // 如果这个地方报错,而没有对异常进行处理的话,就会找不到原因。
            try
            {
                DoSomething(obj);
            }
            catch (Exception ex)
            {
                // 异常处理
            }
        });

        action.BeginInvoke(new object(), null, null);
    }
    catch (Exception ex)
    {
        // 异常处理,这里能捕捉到的是同步调用的异常,而不能捕捉到异步调用的异常
    }
}
10、ajax请求报302 Found
  请求代码如下:
window.RemedyOutTicket = function (json, otherInfo) {
    // json = json.replace(/<br \/>/g, '\r\n'); 加上这句就OK,记得要用正则表达式。不然一次replace只能替换一个<br />
    $.ajax({
        url: "/Test/DoSomething",
        type: "POST",
        data: { json: json, otherInfo: otherInfo },
        cache: false,
        async: true,
        success: function (ret) {
            data = JSON.parse(ret);
            // TODO
        },
        error: function (e) {
            layer.alert("失败");
        }
    });
};

结果返回:302 Found。在没加async:true之前,是在error信息中,报的是未知错误,加上async:true之后,抱错在success中,返回html格式的信息,也是:未知错误。百度搜索了一下也没找到什么有效的办法,于是就在MVC中打断点,发现直接报错为:form提交存在安全隐患,原因是:json字符串中包含:<br />。

解决办法:替换<br />为\r\n之后。搞定。

10、ajax请求报:无法向会话状态服务器发出会话状态请求

ajax请求报:无法向会话状态服务器发出会话状态请求。请确保 ASP.NET State Service (ASP.NET 状态服务)已启动,并且客户端端口与服务器端口相同。如果服务器位于远程计算机上,请检查 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters\AllowRemoteConnection 的值,确保服务器接受远程请求。如果服务器位于本地计算机上,并且上面提到的注册表值不存在或者设置为 0,则状态服务器连接字符串必须使用“localhost”或“127.0.0.1”作为服务器名称。

http://www.cnblogs.com/lcl_1015/articles/2038103.html

 

11、ThrowCryptogaphicException

错误信息:

System.Security.Cryptography.CryptographicException.ThrowCryptogaphicException(Int32 hr)
在 System.Security.Cryptography.X509Certificates.X509Utils._LoadCertFromFile(String fileName, IntPtr password, UInt32 dwFlags, Boolean persistKeySet, SafeCertContextHandle& pCertCtx)
在 System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromFile(String fileName, Object password, X509KeyStorageFlags keyStorageFlags)
在 System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(String fileName, String password)
在 Better.AlipayInterface.InterfaceUtility.GetRequestResult(String requestUrl, Int32 timeout, SendMethod requestMethod, String codeName, String certFile, String certPasswd)

解决方法:

http://stackoverflow.com/questions/9951729/x509certificate-constructor-exception

即:应用程序池--->高级设置--->加载用户配置文件设置为True

12、记用ajax的一个bug

遇到一个bug,IE8,只有第一次功能正确,后面都不生效。我看了一下,确实IE存在问题,调试发现根本不进入后台,于是我猜测是缓存的问题,于是加上cache:false,解决了问题。

 $.ajax(
        {
            url: "ParaSetting/OpenOrCloseParam",
            data: {
                Id: id
            },
            cache:false,
            type: "get",
            success: function (data) {
                alert(data);
                if (data === "操作失败") {
                    layer.alert("操作失败");
                }
                else {
                    window.location.reload();
                }
            },
            error: function (e) {
                alert(e);
            }
        });

后来新同学百度一下,发现jquery中 cache: true和false的区别如下:
true的话会读缓存,可能真的到服务器上。

假如上次访问了a.html,第二次的时候得到的是上次访问的a.html的结果,而不是重新到服务器获取。
false的话会在url后面加一个时间缀,让它跑到服务器获取结果。
cache只有GET方式的时候有效。

13、多线程索引超限制

错误日志如下:

System.ArgumentOutOfRangeException: 索引超出范围。必须为非负值并小于集合大小。
参数名: index
   在 System.ThrowHelper.ThrowArgumentOutOfRangeException()
   在 System.Collections.Generic.List`1.RemoveAt(Int32 index)
   在 System.Collections.Generic.List`1.Remove(T item)
   在 *** 位置***.cs:行号 118

 跟到代码发现是这样一句:dealingTaskList是List<string>,taskID是string。

dealingTaskList.Remove(taskID);

  怎么看都不会出现问题,但结果就是出现问题了,于是我就改成下面这个:

if (dealingTaskList != null && dealingTaskList.Exists(sa => sa == taskID))
{
    dealingTaskList.Remove(taskID);
}

  结果还是报错,实在没有办法了,只好记日志看看是不是出现在这个地方。但是中途我又想起他们好像是开线程做的,会不会是多线程的时候出现问题呢?于是我把代码改成下面这个样子。为防止万一,我还是把日志记上。

lock (lockObj)
{
    if (dealingTaskList != null && dealingTaskList.Exists(sa => sa == taskID))
    {
        temp += "[ex进入]";
        dealingTaskList.Remove(taskID);
        temp += "[ex移除成功]";
    }
    else
    {
        temp += "[ex不满足条件]";
    }
}

  问题解决。

待续.....

推荐阅读