2018-01-09 .NET數據庫連接和參數化查詢、改變超鏈接樣式、Asp.Net底層解析-頁面生命周期、 iOS獲取系統電量、javascript使用的兩項原則

第一組:劉聰 .NET數據庫連接和參數化查詢

.NET中連接MySql數據庫
  1. 引用MySql.Data:.NET框架一般連接數據庫為SQL SERVER 數據庫,如果需要連接Mysql數據庫,則需要添加專用的引用。從官網http://dev.mysql.com/downloads/connector/net/下載最新的MySQL connection/Net組件mysql-connector-net-6.10.5.msi并運行后,在本地C:\Program Files (x86)\MySQL\MySQL Connector Net 6.10.5\Assemblies\v4.5.2路徑下得到MySql.Data.dll(如果沒有也可能在C:\Program Files下)。

  2. 建立數據庫連接
    添加引用后可以使用using MySql.Data.MySqlClient;通過下列代碼實現MySql數據庫連接。


  3. 數據庫操作
    這里只進行簡單的查詢操作:


控制臺輸出:

參數化查詢
  1. SQL注入問題

上面的查詢操作是通過查詢字符串拼接實現的,模擬用戶輸入。這里存在一個SQL注入的問題:


問題在于password = "111' or '1'='1";最后拼成的sql語句為:
select * from usertable where UserName='congliu' AND Password ='111' or '1'='1'
由于1=1恒為真,所以不管其他的輸入為什么都會返回當前表的所有信息。這是一個簡單的sql注入。

  1. 參數化查詢

為了解決這個問題,比較好的方法是采用參數化查詢:



參數化查詢是訪問數據庫時,在需要填入數值或數據的地方,使用參數 (Parameter) 來給值。
  
在使用參數化查詢的情況下,數據庫服務器不會將參數的內容視為SQL指令的一部份來處理,而是在數據庫完成SQL指令的編譯后,才套用參數運行,因此就算參數中含有指令,也不會被數據庫運行。Access、SQL Server、MySQL、SQLite等常用數據庫都支持參數化查詢。


第二組:趙彩鳳 改變超鏈接樣式、AppCan--Switch開關組件

  1. 改變超鏈接樣式
<style type="text/css">
a:link {color: #FF0000}     /* 未訪問的鏈接 */
a:visited {color: #00FF00}  /* 已訪問的鏈接 */
a:hover {color: #FF00FF}    /* 鼠標移動到鏈接上 */
a:active {color: #0000FF}   /* 選定的鏈接 */
</style>
  1. AppCan--Switch開關組件

(1)對象

appcan.switchBtn(selector, css, callback)
Selector  按鈕的選擇器,例如 .btn、div或#id??赏瑫r處理多個按鈕
css Switch  開啟后的背景CSS類名稱。預置 bc-head。可選參數 
callback switch  狀態變更后的回調函數

(2)代碼
HTML:

 <div class="switch uba bc-border data-checked="true">
        <div class="switch-btn sc-bg-active "></div>
</div>

JS:

appcan.switchBtn(switchBtns,function(obj,value) {
            console.log(“switch status:”,value);
})
appcan.updateSwitch(obj);//obj:需要操作的dom對象

E.g.

<div class="switch uba bc-border" data-checked="true">
    <div class="switch-btn sc-bg-active "></div>
</div>
appcan.updateSwitch($('.switch'))

第三組:蔡永堅 Asp.Net底層解析-頁面生命周期

頁面生命周期總體理解起來其實很容易,說白了就是在客戶端提出了一個頁面請求之后,服務器端將ASPX頁面源代碼轉化為正確的HTML和JS代碼的整個過程。服務端在轉化的過程中當然不是調用一兩個方法就能解決了的,是經歷被設計好的若干個階段,一步一步完成的,且各個階段的功能很明確彼此是承前啟后的關系。這些階段大體上可以分為:初始化、加載、回發事件處理、呈現、卸載等等。關于這些階段的具體細節本文將在后面說明,現在先來看一個簡單的從整體上反映頁面生命周期的實例(頁面周期每達到一個事件時,就往頁面中寫入一些字符串),新建一個空頁面,并在后臺編寫以下代碼:

[csharp] view plain copy
1.  protected void Page_PreInit(object sender, EventArgs e)  
2.  {   //這里設置斷點  
3.      Response.Write("執行Page_PreInit<br/>");  
4.  }  
5.  protected void Page_Init(object sender, EventArgs e)  
6.  {   //這里設置斷點  
7.      Response.Write("執行Page_Init<br/>");  
8.  }  
9.  protected void Page_InitComplete(object sender, EventArgs e)  
10. {   //這里設置斷點  
11.     Response.Write("執行Page_InitComplete<br/>");  
12. }  
13. protected void Page_PreLoad(object sender, EventArgs e)  
14. {   //這里設置斷點  
15.     Response.Write("執行Page_PreLoad<br/>");  
16. }  
17. protected void Page_Load(object sender, EventArgs e)  
18. {   //這里設置斷點  
19.     Response.Write("執行Page_Load<br/>");  
20. }  
21. protected void Page_LoadComplete(object sender, EventArgs e)  
22. {   //這里設置斷點  
23.     Response.Write("執行Page_LoadComplete<br/>");  
24. }  
25. protected void Page_PreRender(object sender, EventArgs e)  
26. {   //這里設置斷點  
27.     Response.Write("執行Page_PreRender<br/>");  
28. }  
29. protected void Page_PreRenderComplete(object sender, EventArgs e)  
30. {   //這里設置斷點  
31.     Response.Write("執行Page_PreRenderComplete<br/>");  
32. }  
33. protected void Page_SaveStateComplete(object sender, EventArgs e)  
34. {   //這里設置斷點  
35.     Response.Write("執行Page_SaveStateComplete<br/>");  
36. }  
37. protected void Page_Unload(object sender, EventArgs e)  
38. {   //這里設置斷點  
39.     //這里是頁面卸載階段,不能使用Response.Write方法,一般該事件內執行釋放本頁面控制的系統資源  
40. }   

如果在每個方法的內部都設置了斷點,那么當運行該頁面后會發現,斷點的觸發是從頂部往底部依次執行的,觸發一個事件之后再觸發下一步事件,有條不紊,最終得到頁面效果如下截圖所示:

上面的示例是每次頁面(無論是首次請求還是PostBack)的請求都要觸發的一系列事件,而當請求為PostBack時,會在Page_Load事件與Page_LoadComplete事件之間觸發引起本次PostBack的控件對應的事件,在上面的示例上進行簡單的修改,前臺頁面添加Bot同控件,代碼如下:

[html] view plain copy
1.  <form id="form1" runat="server">  
2.  <asp:Button ID="aspbtn_TestPostBack" runat="server" Text="點擊提交"   
3.      onclick="aspbtn_TestPostBack_Click" />  
4.  </form>  

后臺代碼與上面的示例一致,只是添加了Button控件的Click事件對應的方法,添加的方法如下:

[csharp] view plain copy
1.  //這里是Button的Click事件  
2.  protected void aspbtn_TestPostBack_Click(object sender, EventArgs e)  
3.  {  
4.      Response.Write("執行Button控件的Click事件<br/>");  
5.  }  

首次運行頁面得到結果與上次示例一致,而當點擊按鈕產生PostBack時,發現在Page_Load事件與Page_LoadComplete事件之間執行了按鈕的事件,即aspbtn_TestPostBack_Click方法。


第四組:張元一 iOS獲取系統電量

EFB項目中,需要實現后臺持續監控電量的功能,這可以拆分為三個需求:

  1. 程序需要保持在后臺可以運行。
  2. 程序需要獲取ipad精確電量。
  3. 需要每隔一段時間掃描一次電量,以獲取當前有效的電量。

上次文章實現了需求一,本文先討論需求二的實現:
獲取ios系統電量,有幾種方法:

方法一:

通過蘋果官方文檔里面UIDevice public API來獲取,代碼如下:

 [UIDevice currentDevice].batteryMonitoringEnabled = YES;
    [[NSNotificationCenter defaultCenter]
   addObserverForName:UIDeviceBatteryLevelDidChangeNotification
     object:nil queue:[NSOperationQueue mainQueue]
     usingBlock:^(NSNotification *notification) {
         self.myVC.batteryLevellb.text = [NSString stringWithFormat:@"CurrentBatteryLevel:%.f%%",[UIDevice currentDevice].batteryLevel*100];
}];

方法獲取的電量是1%精度的,可以滿足要求。

方法二:通過runtime 獲取StatusBar上電池電量控件類私有變量的值,此方法可精準獲取iOS6以上電池電量
- (int)getCurrentBatteryLevel
{
    
    UIApplication *app = [UIApplication sharedApplication];
    if (app.applicationState == UIApplicationStateActive||app.applicationState==UIApplicationStateInactive) {
        Ivar ivar=  class_getInstanceVariable([app class],"_statusBar");
        id status  = object_getIvar(app, ivar);
        for (id aview in [status subviews]) {
            int batteryLevel = 0;
            for (id bview in [aview subviews]) {
                if ([NSStringFromClass([bview class]) caseInsensitiveCompare:@"UIStatusBarBatteryItemView"] == NSOrderedSame&&[[[UIDevice currentDevice] systemVersion] floatValue] >=6.0)
                {
                    
                    Ivar ivar=  class_getInstanceVariable([bview class],"_capacity");
                    if(ivar)
                    {
                        batteryLevel = ((int (*)(id, Ivar))object_getIvar)(bview, ivar);
                        //這種方式也可以
                        /*ptrdiff_t offset = ivar_getOffset(ivar);
                         unsigned char *stuffBytes = (unsigned char *)(__bridge void *)bview;
                         batteryLevel = * ((int *)(stuffBytes + offset));*/
                        NSLog(@"電池電量:%d",batteryLevel);
                        if (batteryLevel > 0 && batteryLevel <= 100) {
                            return batteryLevel;
                            
                        } else {
                            return 0;
                        }
                    }
                    
                }
                
            }
        }
    }
    
    return 0;
}

經測試,此方法獲取電量精度為5%,且在程序退出到后臺后,此方法不能獲取到電量,不能滿足要求。

方法三:

通過IOKit framework來獲取

IOKit framework在IOS中用來跟硬件或內核服務通信,常用于獲取硬件詳細信息。

首先,需要將IOPowerSources.h,IOPSKeys.h,IOKit三個文件導入到工程中。然后即可通過如下代碼獲取1%精確度的電量信息:

-(double) getBatteryLevel{
    // returns a blob of power source information in an opaque CFTypeRef
    CFTypeRef blob = IOPSCopyPowerSourcesInfo();
    // returns a CFArray of power source handles, each of type CFTypeRef
    CFArrayRef sources = IOPSCopyPowerSourcesList(blob);
    CFDictionaryRef pSource = NULL;
    const void *psValue;
    // returns the number of values currently in an array
    int numOfSources = CFArrayGetCount(sources);
    // error in CFArrayGetCount
    if (numOfSources == 0) {
        NSLog(@"Error in CFArrayGetCount");
        return -1.0f;
    }
    
    // calculating the remaining energy
    for (int i=0; i<numOfSources; i++) {
        // returns a CFDictionary with readable information about the specific power source
        pSource = IOPSGetPowerSourceDescription(blob, CFArrayGetValueAtIndex(sources, i));
        if (!pSource) {
            NSLog(@"Error in IOPSGetPowerSourceDescription");
            return -1.0f;
        }
        psValue = (CFStringRef) CFDictionaryGetValue(pSource, CFSTR(kIOPSNameKey));
        
        int curCapacity = 0;
        int maxCapacity = 0;
        double percentage;
        
        psValue = CFDictionaryGetValue(pSource, CFSTR(kIOPSCurrentCapacityKey));
        CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &curCapacity);
        
        psValue = CFDictionaryGetValue(pSource, CFSTR(kIOPSMaxCapacityKey));
        CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &maxCapacity);
        
        percentage = ((double) curCapacity / (double) maxCapacity * 100.0f);
        NSLog(@"curCapacity : %d / maxCapacity: %d , percentage: %.1f ", curCapacity, maxCapacity, percentage);
        return percentage;
    }
    return -1.0f;
}

相比方法一,此方法麻煩很多,不過現在的EFB使用的是這種方式。

本項目demo的GitHub地址:
https://github.com/Frued/BatteryLevel


第五組:陳孚楠 javascript使用的兩項原則

兩項原則之平穩退化和漸進增強

  1. 平穩退化
    如果正確地使用了JavaScript腳本,就可以讓訪問者在他們瀏覽器不支持javascript的情況下仍能順利地瀏覽你的網站。
    即當客戶禁止javascript功能后,仍能看到網頁的內容。

  2. 漸進增強
    即用一些額外的信息層去包裹原始數據。若按照“漸進增強”原則創建的網頁幾乎都能符合“平穩退化”原則。
    例如:先只使用常規的鏈接,然后通過JavaScript去攔截默認動作。同理:先構建常規網站,然后再Hijax它
    大概可以說:
    “平穩退化”是在瀏覽器沒有JavaScript功能,或沒有開啟JavaScript功能情況下,我們解決這種問題的方式;
    “漸進增強”是在瀏覽器開啟JavaScript功能后,如果瀏覽器版本不支持某些JavaScript能力,我們解決這種問題的方式。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,556評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,463評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,009評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,778評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,218評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,436評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,969評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,795評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,993評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,229評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,659評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,917評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,687評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,990評論 2 374