All posts by 龙生

使用Log4net记录日志

首先说说为什么要进行日志记录。在一个完整的程序系统里面,日志系统是一个非常重要的功能组成部分。它可以记录下系统所产生的所有行为,并按照某种规范表达出来。我们可以使用日志系统所记录的信息为系统进行排错,优化系统的性能,或者根据这些信息调整系统的行为。 Log4net是一个很著名的开源的日志记录组件。官方网址为:http://logging.apache.org/log4net/ ,使用Log4net能够很简单的为我们的程序添加日志记录功能。下面我们先通过一个网站例子来说明如何在.net中使用log4net。 创建日志记录步骤 第一步, 当然是添加log4net.dll的引用啦,我这里提供一个log4net的dll文件,懒得去官网下的可以到这里下http://www.vdisk.cn/down/index/7509396A7366 第二步, 在AssemblyInfo.cs文件中添加下面一句话: 1 [assembly: log4net.Config.XmlConfigurator(ConfigFile = "Web.config", Watch = true)] 这句话的意思是log4net会自动寻找配置文件App.config或Web.config从而获得并加载其中的配置信息。如果想log4net随时监视配置文件以便重新加载的话就要这样写按照上面一样写(winform程序ConfigFile为App.config)。 第三步, 配置Web.config。

上面这段配置取自周公,配置的说明上面已经注释的比较详细了。 第四步, 在程序中记录信息。我们在项目下Default.aspx的Page_Load方法加入如下代码:

然后运行项目,可以发现在c:\log4netfile.txt中已经记录了一条日志信息:

通过上面这几步我想您已经能够为程序创建一些简单日志记录功能了。下面我们再来详细说说log4net其他的一些使用方法与特点。 log4net详细说明 这里我通过问答的形式来说明log4net的一些应用。 1.log4net总共有几种记录方式,每种方式该如何配置与使用? Log4net目前支持的输出方式包括:

  可以看到目前支持的方式还是很多的,我这里调几个认为常用的做个例子。 1.文件的方式我们上面已经讲过了,这里不再做例子了。 2.数据库方式: 首先,添加数据库记录appender

然后建立c:log4net.mdb 数据库,并在代码中启用数据库记录方式:

这样日志就被记录到数据库中了。 2.log4net如何过滤我想要的日志信息,比如一个日志中只记录程序错误日志? 这个需求可以通过配置filter来实现。具体操作如下: 全局方式: 这种方式会将级别应用于所有的日志输入方式。具体操作为在root节点下添加:

这样对于所有的日志记录方式,所有地域ERROR级别的都不会被记录了。 单独配置级别方式:       该方式不会影响其他的日志输入方式。方法如下为,在具体的appender下添加filter:

这种方式可以配置记录级别的方位,如果只需要记录一种,则最大和最小设置一样就行了。 3.你上面的日志输出格式我不喜欢,如何在log4net中配置我想要的日志输出格式? log4net的输入格式定义在每个appender的layout中。具体的有以下内置可选项: %m(message):输出的日志消息,如ILog.Debug(…)输出的一条消息 %n(new line):换行 %d(datetime):输出当前语句运行的时刻 %r(run time):输出程序从运行到执行到当前语句时消耗的毫秒数 %t(thread id):当前语句所在的线程ID %p(priority): 日志的当前优先级别,即DEBUG、INFO、WARN…等 %c(class):当前日志对象的名称,例如: %f(file):输出语句所在的文件名。 %l(line):输出语句所在的行号。 %数字:表示该项的最小长度,如果不够,则用空格填充,如“%-5level”表示level的最小宽度是5个字符,如果实际长度不够5个字符则以空格填充。 通过这些东西,你可以任意组合你喜欢的输出格式内容。   4.有没有方式控制程序自动按日期记录日志信息,即每天的日志都在不同的日志文件中? 其实这种方式对应于一种特定的记录方式:RollingFileAppender。这种方式也是基于文件记录的,不过他提供更加灵活的日志记录方式。具体说来他可以按日志文件的大小或者日志记录的时间进行自动变换日志文件。 按每天不同的日期进行记录分类:

按照日志文件的大小进行变换,通过这种方式可以有效降低日志文件体积膨胀的问题:

最后从网上找了一段写日志的原则,感觉还是很好的: 【写日志的原则】 Ⅰ.在catch后,把异常写入日志. Ⅱ.在调用第三方控件的开始和结束处. Ⅲ.在连接数据库的开始结束处. Ⅳ.除非必要,不要在循环体中加入日志,否则一旦出问题可能导致日志暴增. Ⅴ.在自己认为很重要的逻辑处写入日志.   如果要将log方法写在类库里面,那么可以参考这篇文章http://hi.baidu.com/sjbh/blog/item/10cda8d689fb0c3807088b87.html from:http://www.cnblogs.com/qianlifeng/archive/2011/04/22/2024856.html

龙生   02 Sep 2014
View Details

C#编写Windows服务程序图文教程

Windows Service这一块并不复杂,但是注意事项太多了,网上资料也很凌乱,偶尔自己写也会丢三落四的。所以本文也就产生了,本文不会写复杂的东西,完全以基础应用的需求来写,所以不会对Windows Service写很深入。 本文介绍了如何用C#创建、安装、启动、监控、卸载简单的Windows Service 的内容步骤和注意事项。 一、创建一个Windows Service 1)创建Windows Service项目 2)对Service重命名 将Service1重命名为你服务名称,这里我们命名为ServiceTest。 二、创建服务安装程序 1)添加安装程序 之后我们可以看到上图,自动为我们创建了ProjectInstaller.cs以及2个安装的组件。 2)修改安装服务名 右键serviceInsraller1,选择属性,将ServiceName的值改为ServiceTest。 3)修改安装权限 右键serviceProcessInsraller1,选择属性,将Account的值改为LocalSystem。 三、写入服务代码 1)打开ServiceTest代码 右键ServiceTest,选择查看代码。 2)写入Service逻辑 添加如下代码:

这里我们的逻辑很简单,启动服务的时候写个日志,关闭的时候再写个日志。 四、创建安装脚本 在项目中添加2个文件如下(必须是ANSI或者UTF-8无BOM格式): 1)安装脚本Install.bat

2)卸载脚本Uninstall.bat

3)安装脚本说明 第二行为启动服务。 第三行为设置服务为自动运行。 这2行视服务形式自行选择。 4)脚本调试 如果需要查看脚本运行状况,在脚本最后一行加入pause 五、在C#中对服务进行控制 0)配置目录结构 简历一个新WPF项目,叫WindowsServiceTestUI,添加对System.ServiceProcess的引用。 在WindowsServiceTestUI的bin\Debug目录下建立Service目录。 将WindowsServiceTest的生成目录设置为上面创建的Service目录。 生成后目录结构如下图 1)安装 安装时会产生目录问题,所以安装代码如下:

2)卸载 卸载时也会产生目录问题,所以卸载代码如下:

3)启动 代码如下:

4)停止

5)暂停/继续

6)检查状态

六、调试Windows Service 1)安装并运行服务 2)附加进程 3)在代码中加入断点进行调试 七、总结 本文对Windows service的上述配置都未做详细解释,但是按上述步骤就可以制作可运行的Windows Service,从而达到了工作的需求。 FROM:http://www.cr173.com/html/15350_1.html

龙生   01 Sep 2014
View Details

页面超过了最大请求长度问题

今天遇到了这样的事情,“页面超过了最大请求长度问题” “/AppShop”应用程序中的服务器错误。 超过了最大请求长度。 说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。 异常详细信息: System.Web.HttpException: 超过了最大请求长度。 源错误: 执行当前 Web 请求期间生成了未处理的异常。可以使用下面的异常堆栈跟踪信息确定有关异常原因和发生位置的信息。 堆栈跟踪: [HttpException (0x80004005): 超过了最大请求长度。] System.Web.HttpRequest.GetEntireRawContent() +8766626 System.Web.HttpRequest.GetMultipartContent() +62 System.Web.HttpRequest.FillInFormCollection() +168 System.Web.HttpRequest.get_Form() +68 System.Web.HttpRequest.get_HasForm() +8722023 System.Web.UI.Page.GetCollectionBasedOnMethod(Boolean dontReturnNull) +97 System.Web.UI.Page.DeterminePostBackMode() +63 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +133 问题:在百万行数据表中真分页查询,页面上有一DropDownList用来选择页码,达到十万个下拉项,viewstate=true。         在页面回传时,产生超过了最大请求长度的  问题 分析:这可能是由于viewstate包含数据量过大,引起回传request包含数据量过大。 解决方案:可以在webconfig文件中修改最大请求长度。 <configuration> <system.web> <httpRuntime  maxRequestLength="10000"     ……> </system.web> </configuration> 结果:先设为1000,不通过,设为10000后,通过 总结:或进行二级分页可能更好 FORM:http://www.cnblogs.com/wenanry/archive/2009/04/16/1437094.html

龙生   28 Aug 2014
View Details

主流JS库一览

目前来看,JS框架以及一些开发包和库类有如下几个,Dojo 、Scriptaculous 、Prototype 、yui-ext 、Jquery 、Mochikit、mootools 、moo.fx Dojo (JS library and UI component ): Dojo 是目前最为强大的j s框架,它在自己的Wiki上给自己下了一个定义,dojo是一个用JavaScript编写的开源的DHTML工具箱。dojo很想做一个“大一统”的 工具箱,不仅仅是浏览器层面的,野心还是很大的。Dojo包括ajax, browser, event, widget等跨浏览器API,包括了JS本身的语言扩展,以及各个方面的工具类库,和比较完善的UI组件库,也被广泛应用在很多项目中,他的UI组件的 特点是通过给html标签增加tag的方式进行扩展,而不是通过写JS来生成,dojo的API模仿Java类库的组织方式。 用dojo写Web OS可谓非常方便。dojo现在已经4.0了,dojo强大的地方在于界面和特效的封装,可以让开发者快速构建一些兼容标准的界面。 优点:库相当完善,发展时间也比较长,功能强大,据说利用dojo的io.bind()可以实现comet,看见其功能强大非一般,得到IBM和SUN的支持 缺点:文件体积比较大,200多KB,初次下载相当慢,此外,dojo的类库使用显得不是那么易用,j s语法增强方面不如prototype。 Prototype (JS OO library): 是一个非常优雅的JS库,定义了JS的面向对象扩展,DOM操作API,事件等等,以prototype为核心,形成了一个外围的各种各样的JS扩展库,是相当有前途的JS底层框架,值得推荐,感觉也是现实中应用最广的库类(RoR集成的AJAX JS库),之上还有 Scriptaculous 实现一些JS组件功能和效果。 优点:基本底层,易学易用,甚至是其他一些js特效开发包的底层,体积算是最小的了。 缺点:如果说缺点,可能就是功能是他的弱项 Scriptaculous (JS UI component based on prototype): Scriptaculous 是基于prototype.js框架的JS效果。包含了6个js文件,不同的文件对应不同的js效果,所以说,如果底层用 prototype的话,做js效果用Scriptaculous那是再合适不过的了,连大名鼎鼎的digg都在用他,可见不一般 优点:基于prototype是最大的优点,由于使用prototype的广泛性,无疑对用户书锦上添花,并且在《ajax in action》中就拿Scriptaculous来讲述js效果 缺点:刚刚兴起,需要时间的磨练 yui-ext (JS UI component): 基 于Yahoo UI的扩展包yui-ext是具有CS风格的Web用户界面组件能实现复杂的Layout布局,界面效果可以和backbase媲美,而且使用纯 javascript代码开发。真正的可编辑的表格Edit Grid,支持XML和Json数据类型,直接可以迁入grid。许多组件实现了对数据源的支持,例如动态的布局,可编辑的表格控件,动态加载的Tree 控件、动态拖拽效果等等。1.0 beta版开始同Jquery合作,推出基于jQuery的Ext 1.0,提供了更多有趣的功能。 优点:结构化,类似于java的结构,清晰明了,底层用到了Jquery的一些函数,使整合使用有了选择,最重要的一点是界面太让让人震撼了。 缺点:太过复杂,整个界面的构造过于复杂。 Jquery : jQuery是一款同prototype一样优秀js开发库类,特别是对css和XPath的支持,使我们写js变得更加方便!如果你不是个js高手又想写出优秀的js效果,jQuery可以帮你达到目的!并且简介的语法和高的效率一直是jQuery追求的目标, 优点:注重简介和高效,js效果有yui-ext的选择,因为yui-ext 重用了很多jQuery的函数 缺点:据说太嫩,历史不悠久。 Mochikit : MochiKit 自称为一个轻量级的js框架。MochiKit 主要受到 Python 和 Python 标准库提供的很多便利之处的启发,另外还缓解了浏览器版本之间的不一致性。其中的 MochiKit.DOM 尤其方便,能够以比原始 JavaScript 更友好的方式处理 DOM 对象。MochiKit.DOM 大部分都是针对 XHTML […]

龙生   28 Aug 2014
View Details

在asp.net中发送图片到远程服务器上

发送代码: var imgFile = Request.Files["imgFile"]; if (imgFile == null) return; var img = Image.FromStream(imgFile.InputStream); var ms = new MemoryStream(); img.Save(ms,ImageFormat.Jpeg); var data = new byte[ms.Length]; ms.Seek(0, SeekOrigin.Begin); ms.Read(data, 0, Convert.ToInt32(ms.Length)); ms.Dispose(); var fileName = imgFile.FileName; var fileType = imgFile.ContentType; var fileSize = data.Length.ToString(); var myRequest = WebRequest.Create(Common.ImgUrl + "/upload/UploadImg.aspx"); myRequest.Method = "POST"; myRequest.ContentType = fileType; myRequest.ContentLength = data.Length; myRequest.Headers.Add("FileType", Server.UrlEncode(fileType)); myRequest.Headers.Add("FileSize", fileSize); myRequest.Headers.Add("FileName", Server.UrlEncode(fileName)); myRequest.Headers.Add("dir", Server.UrlEncode(Request["dir"])); using (var newStream = myRequest.GetRequestStream()) { // Send the data. newStream.Write(data, 0, data.Length); newStream.Close(); } // Get response var myResponse = myRequest.GetResponse(); […]

龙生   27 Aug 2014
View Details

利用InputStream 属性直接从HttpPostedFile对象读取文本内容

//利用InputStream 属性直接从HttpPostedFile对象读取文本内容 System.IO.Stream MyStream; int FileLen; FileLen = file.ContentLength; // 读取文件的 byte[] byte[] bytes = new byte[FileLen]; MyStream = file.InputStream; MyStream.Read(bytes, 0, FileLen); from:http://blog.csdn.net/yyixin/article/details/5336899

龙生   27 Aug 2014
View Details

WebRequest 对象的使用

from:http://www.cnblogs.com/haogj/archive/2011/06/09/2076708.html

龙生   27 Aug 2014
View Details

使用HttpWebRequest实现大文件上传

Author:xuzhihong Create Date:2011-06-03 Descriptions: WinForm程序使用HttpWebRequest实现大文件上传 概述: 通常在WinForm程序中都是采用WebClient方式实现文件上传功能,本身这个方式没有问题,但是当需要上传大文件比如说(300+M)的时候,那么WebClient将会报内存不足异常(Out of Memory Exceptions),究其原因是因为WebClient方式是一次性将整个文件全部读取到本地内存中,然后再以数据流形式发送至服务器。本文将讲述如何采用HttpWebRequest方式每次读取固定大小数据片段(如4KB)发送至服务器,为大文件上传提供解决方案,本文还将详细讲述将如何将“文件上传”功能做为用户自定义控件,实现模块重用。   关键词:HttpWebRequest、WebClient、OutOfMemoryExceptions   解决方案: 开始我在WinForm项目中实现文件上传功能的时候,是采用WebClient(WebClient myWebClient = new WebClient();)方式,这大部分情况都是正确的,但有时候会出现内存不足的异常(Out of Memory Exceptions),经常测试,发现是由于上传大文件的时候才导致这问题。在网上查阅了一下其他网友的解决方案,最后找的发生异常的原因:“WebClient方式是一次性将整个文件全部读取到本地内存中,然后再以数据流形式发送至服务器”,详细请参考:http://blogs.msdn.com/b/johan/archive/2006/11/15/are-you-getting-outofmemoryexceptions-when-uploading-large-files.aspx 。按照这个解释,那么大文件上传出现内存不足的异常也就不足为奇了。下面我将讲述如何一步步使用HttpWebRequest方式来实现文件分块上传数据流至服务器。 按照惯例还是先预览一下文件上传最后的效果吧,如下图所示:   界面分为两部分,上面是文件基本信息,下面是文件上传自定义控件,我这里实现的是一个案件上传多个监控视频功能。以下是详细步骤: 第一步:创建用户自定义控件BigFileUpload.xaml 文件上传是一个非常常用的功能,为了所写的程序能非常方便地多次重复使用,我决定将其处理为一个用户自定义控件(UserControl)。 我们先在项目中创建一个FileUpload文件夹,在其目录下新建一个WPF自定义控件文件命名为BigFileUpload.xaml,这样就表示文件上传是一个独立的小模块使用。之所以用WPF自定义控件是因为WPF页面效果好看点,而且我想以后可能大部分C/S程序都会渐渐的由WinForm转向WPF吧,当然创建Window Forms用户控件也是没有问题的。然后我们需要做一个下图效果的页面布局:   前台设计代码如下: <UserControl x:Class="CHVM.FileUpload.BigFileUpload" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="160" Width="480"> <Grid Height="160" Width="480" Background="White"> <Label Height="28" HorizontalAlignment="Left" Margin="16,10,0,0" Name="label1" VerticalAlignment="Top" Width="53">文件</Label> <Label HorizontalAlignment="Left" Margin="15,52,0,80" Name="label2" Width="54">进度</Label> <ProgressBar Height="20" Margin="61,52,116,0" Name="progressBar1" VerticalAlignment="Top" /> <TextBox Height="23" Margin="61,12,116,0" Name="txtBoxFileName" VerticalAlignment="Top" /> <Button Height="23" HorizontalAlignment="Right" Margin="0,10,35,0" Name="BtnBrowse" VerticalAlignment="Top" Width="75" Click="BtnBrowse_Click">浏览…</Button> <Button Height="23" HorizontalAlignment="Right" Margin="0,52,35,0" Name="BtnUpload" VerticalAlignment="Top" Width="75" Click="BtnUpload_Click">上传</Button> <Label HorizontalAlignment="Left" Margin="16,0,0,44" Name="lblState" Width="183" Height="35" […]

龙生   27 Aug 2014
View Details

asp.net中使用HttpWebRequest发送上传文件

一个网站中需要上传一个文件到另一个网站,可以使用HttpWebRequest或者WebClient。 但是WebClient需要首先上传文件到服务器,才能执行发送,不太符合我的需求,这里不再介绍。 通过HttpWebRequest发送的原理: 构建一个HttpWebRequest,通过FileUpload获取要上传的文件,通过字节流发送这个文件,另一个网站接收字节流,保存到服务器。 发送程序: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 //获取要上传的文件信息        byte[]data=fileupload1.FileBytes;        stringfileName=fileupload1.FileName;        stringfileType=fileupload1.PostedFile.ContentType;        stringfileSize=data.Length.ToString();        HttpWebRequest myRequest=(HttpWebRequest)WebRequest.Create("http://localhost:8102/Default.aspx");        myRequest.Method="POST";        myRequest.ContentType=fileType;        myRequest.ContentLength=data.Length;        myRequest.Headers.Add("FileType",Server.UrlEncode(fileType));        myRequest.Headers.Add("FileSize",fileSize);        myRequest.Headers.Add("FileName",Server.UrlEncode(fileName));        using(Stream newStream=myRequest.GetRequestStream())        {            // Send the data.            newStream.Write(data,0,data.Length);            newStream.Close();        }        // Get response        HttpWebResponse myResponse=(HttpWebResponse)myRequest.GetResponse();        StreamReader reader=newStreamReader(myResponse.GetResponseStream(),Encoding.UTF8);        stringcontent=reader.ReadToEnd(); 接收程序: 0 1 2 3 4 5 6 7 8 9 10 stringfileName=Server.UrlDecode(Request.Headers["FileName"].ToString());            stringfileType=Server.UrlDecode(Request.Headers["FileType"].ToString());            intfileSize=int.Parse(Request.Headers["FileSize"].ToString());            byte[]bytes=Request.BinaryRead(fileSize);            File.WriteAllBytes(Server.MapPath("~/uploadfiles/"+fileName),bytes);            Response.HeaderEncoding=System.Text.Encoding.UTF8;            Response.Charset="utf-8";            Response.Write("FileType:"+fileType+";FileName:"+fileName+";FileSize:"+fileSize); FROM:http://blog.bossma.cn/dotnet/asp-net-httpwebrequest-upload-send-file/

龙生   27 Aug 2014
View Details

8点1氪:亚马逊落户上海自贸区,美国货直邮中国

36氪微信号:wow36kr 亚马逊落户上海自贸区:美国货直邮中国 亚马逊(中国)投资有限公司宣布与自贸区、上海信投达成合作,三方将在自贸区内合作开展跨境电子商务业务,并在自贸区内建立跨境电子商务平台。 三方的合作内容包括:一是建设跨境电子商务平台,为境内外客户购买亚马逊境外网站和中国网站商品提供服务;二是建设物流仓储平台,为中国企业出口商品配送全球提供物流仓储服务;三是利用自贸实验区金融创新政策,优化亚马逊公司融资结构,合作开展跨境电子支付服务; 上海跨境贸易电子商务试点平台,自去年底正式运营以来,目前备案和上线商家已达 32 家,分别来自日本、韩国、澳大利亚、美国、意大利、法国和香港等国家和地区,已进入备案和上线的品种有近万种,形成了一定的品牌集聚效应。 微软推出Windows物联网操作系统预览版 微软现开始向所有 Windows 物联网开发者出货英特尔 Galileo 主板和配套的 Windows 物联网操作系统预览版,并且可以在一系列第三方合作伙伴,如亚马逊,Fry’s 和 newegg.com 购买。 今年早些时候,该公司推出了 Windows 物联网开发者计划,目的是为小物件装上 Windows 操作系统,微软已经向少数指定的开发者出货少量英特尔 Galileo 主板,和相应的特制 Windows 操作系统 Windows 物联网操作系统是一个“Windows8.1 的非商业版本”,预览版的推出,是微软进军物联网计划的一个重要步骤,让制造商和开发人员创建,产生新的想法,并提供反馈,以帮助微软继续改 Windows 物联网操作系统。 谷歌眼镜新专利曝光:与普通眼镜无外观差异 美国专利商标局于 8 月 12 日批准了谷歌一项将用于“可穿戴式显示设备”的外观设计专利。根据该专利提供的草图,未来谷歌眼镜或将不再有置于镜框外右侧的微型显示屏,取而代之的将是一款电子元件全部内置,且从外观看来与普通眼镜并无差异的设备。 专利持有人 Heinrich 在其个人网站上对该项专利的描述为:“早期机械结构布局。为有关设备的发布引导消费商品包装的开发。考虑了人类因素和物理模型,以适应更多的人配戴。结合了骨传导音频系统,包括元件设计和测试等。大量的高保真和低保真原型开发。” 专利适用于“可穿戴式显示设备”,从外观看与普通眼镜框无明显差异。与当前谷歌眼镜相比,新设计将外置的显示屏幕放在了右侧镜框的内部。 三星首款Nook平板电脑巴诺开卖 三星今天与 Barnes&Noble 联手发布了 Galaxy Tab 4 Nook 平板电脑。这款产品基本上是三星现有 Galaxy Tab 4 平板电脑更名产品,并且预装了一些 Nook 定制软件,该平板电脑拥有 7 英寸显示屏,分辨率 1280×800,售价 179 美元,和三星 Galaxy Tab 4 平板电脑现有价格基本相同。 Barnes&Noble 于 2012 年发布自己的平板电脑,但很快了结相关业务,前后不到一年时间,Nook 平板电脑亏损让 Barnes&Noble 季度财报难堪,以至于它最终宣布剥离该部门,该部门目前专注于电子书阅读器产品。 亚马逊 Kindle Fire HD 平板电脑只卖 139 美元,而 HDX 版本售价为 229 美元。不过,Nook 平板电脑允许访问完整的谷歌 Play 商店,这意味着应用程序选择将远远超过你亚马逊的平板电脑。 传亚马逊将在印度测试无人机送货服务 […]

龙生   21 Aug 2014
View Details
1 308 309 310 413