簡介
該博文記錄了一些平時在工作中遇到的問題及解決辦法,某些問題有解決辦法,某些問題暫時沒有解決辦法,如果有大神知道的,請多多指點。
如果某些問題有更好的解決辦法,也請指教。
知識點
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中操作。