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。可同时处理多个按钮
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阅读 160,444评论 4 365
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,867评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,157评论 0 248
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,312评论 0 214
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,673评论 3 289
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,802评论 1 223
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,010评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,743评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,470评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,696评论 2 250
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,187评论 1 262
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,538评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,188评论 3 240
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,127评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,902评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,889评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,741评论 2 274