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数据库连接。


    2018-01-09 .NET数据库连接和参数化查询、改变超链接样式、Asp.Net底层解析-页面生命周期、 iOS获取系统电量、javascript使用的两项原则_第1张图片
  3. 数据库操作
    这里只进行简单的查询操作:


    2018-01-09 .NET数据库连接和参数化查询、改变超链接样式、Asp.Net底层解析-页面生命周期、 iOS获取系统电量、javascript使用的两项原则_第2张图片

控制台输出:

2018-01-09 .NET数据库连接和参数化查询、改变超链接样式、Asp.Net底层解析-页面生命周期、 iOS获取系统电量、javascript使用的两项原则_第3张图片
参数化查询
  1. SQL注入问题

上面的查询操作是通过查询字符串拼接实现的,模拟用户输入。这里存在一个SQL注入的问题:


2018-01-09 .NET数据库连接和参数化查询、改变超链接样式、Asp.Net底层解析-页面生命周期、 iOS获取系统电量、javascript使用的两项原则_第4张图片
2018-01-09 .NET数据库连接和参数化查询、改变超链接样式、Asp.Net底层解析-页面生命周期、 iOS获取系统电量、javascript使用的两项原则_第5张图片

问题在于password = "111' or '1'='1";最后拼成的sql语句为:
select * from usertable where UserName='congliu' AND Password ='111' or '1'='1'
由于1=1恒为真,所以不管其他的输入为什么都会返回当前表的所有信息。这是一个简单的sql注入。

  1. 参数化查询

为了解决这个问题,比较好的方法是采用参数化查询:


2018-01-09 .NET数据库连接和参数化查询、改变超链接样式、Asp.Net底层解析-页面生命周期、 iOS获取系统电量、javascript使用的两项原则_第6张图片

2018-01-09 .NET数据库连接和参数化查询、改变超链接样式、Asp.Net底层解析-页面生命周期、 iOS获取系统电量、javascript使用的两项原则_第7张图片

参数化查询是访问数据库时,在需要填入数值或数据的地方,使用参数 (Parameter) 来给值。
  
在使用参数化查询的情况下,数据库服务器不会将参数的内容视为SQL指令的一部份来处理,而是在数据库完成SQL指令的编译后,才套用参数运行,因此就算参数中含有指令,也不会被数据库运行。Access、SQL Server、MySQL、SQLite等常用数据库都支持参数化查询。


第二组:赵彩凤 改变超链接样式、AppCan--Switch开关组件

  1. 改变超链接样式

  1. AppCan--Switch开关组件

(1)对象

appcan.switchBtn(selector, css, callback)
Selector  按钮的选择器,例如 .btn、div或#id。可同时处理多个按钮
css Switch  开启后的背景CSS类名称。预置 bc-head。可选参数 
callback switch  状态变更后的回调函数

(2)代码
HTML:

 
  

JS:

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

E.g.

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
"); 4. } 5. protected void Page_Init(object sender, EventArgs e) 6. { //这里设置断点 7. Response.Write("执行Page_Init
"); 8. } 9. protected void Page_InitComplete(object sender, EventArgs e) 10. { //这里设置断点 11. Response.Write("执行Page_InitComplete
"); 12. } 13. protected void Page_PreLoad(object sender, EventArgs e) 14. { //这里设置断点 15. Response.Write("执行Page_PreLoad
"); 16. } 17. protected void Page_Load(object sender, EventArgs e) 18. { //这里设置断点 19. Response.Write("执行Page_Load
"); 20. } 21. protected void Page_LoadComplete(object sender, EventArgs e) 22. { //这里设置断点 23. Response.Write("执行Page_LoadComplete
"); 24. } 25. protected void Page_PreRender(object sender, EventArgs e) 26. { //这里设置断点 27. Response.Write("执行Page_PreRender
"); 28. } 29. protected void Page_PreRenderComplete(object sender, EventArgs e) 30. { //这里设置断点 31. Response.Write("执行Page_PreRenderComplete
"); 32. } 33. protected void Page_SaveStateComplete(object sender, EventArgs e) 34. { //这里设置断点 35. Response.Write("执行Page_SaveStateComplete
"); 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.  
2. 4.

后台代码与上面的示例一致,只是添加了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事件
"); 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

相比方法一,此方法麻烦很多,不过现在的EFB使用的是这种方式。

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


第五组:陈孚楠 javascript使用的两项原则

两项原则之平稳退化和渐进增强

  1. 平稳退化
    如果正确地使用了JavaScript脚本,就可以让访问者在他们浏览器不支持javascript的情况下仍能顺利地浏览你的网站。
    即当客户禁止javascript功能后,仍能看到网页的内容。

  2. 渐进增强
    即用一些额外的信息层去包裹原始数据。若按照“渐进增强”原则创建的网页几乎都能符合“平稳退化”原则。
    例如:先只使用常规的链接,然后通过JavaScript去拦截默认动作。同理:先构建常规网站,然后再Hijax它
    大概可以说:
    “平稳退化”是在浏览器没有JavaScript功能,或没有开启JavaScript功能情况下,我们解决这种问题的方式;
    “渐进增强”是在浏览器开启JavaScript功能后,如果浏览器版本不支持某些JavaScript能力,我们解决这种问题的方式。

你可能感兴趣的:(2018-01-09 .NET数据库连接和参数化查询、改变超链接样式、Asp.Net底层解析-页面生命周期、 iOS获取系统电量、javascript使用的两项原则)