[转载]最短的javascript: 地址栏载入脚本

mikel阅读(1583)

[转载]【挑战极限】最短的javascript: 地址栏载入脚本 – EtherDream – 博客园.

相信大家都在地址栏里用JavaScript:的形式执行过脚本。这种方法简单实用,测试比较短的脚本时经常用到。

不过脚本比较长的时候,需要复制密密麻麻一大段到地址栏里,显得很不美观,而且脚本修改起来也很不容易。因此一般先把脚本写在单独一个文件里,然后用JavaScript: 的形式动态载入脚本到页面中。不少网页插件都是用这个方法载入。

平时,我们用最简单的代码实现动态载入:

javascript:var o=document.createElement('script');o.src='...';document.body.appendChild(o);void(0)

当然,这对于载入插件来说足够OK了。但是不久前看到一个稍有修改的方法,让我开始琢磨这段代码究竟可以压缩到多短!

他的代码大致相同,只是更严谨:

javascript:(function(o){o.src='...';document.body.appendChild(o)})(document.createElement('script'));void(0)

虽然代码比先前的还长,但是将变量置于闭包中,避免潜在的冲突。并且将  document.createElement作为闭包的参数,巧妙的节省了一个var单词。

闲来无事,于是考虑起这代码能否精简再精简。顺便复习下js里面的各种特性。

当然,首先默认了几个地址栏载入脚本要遵循的规则:

1. 不引入全局变量

2. 兼容主流浏览器

3. 载入过程不影响页面

> 不影响全局变量,我们需要使用闭包来隐藏我们的私有变量;

> 兼容主流浏览器,就必须使用标准的方法,兼容性判断只会增加代码长度;

> 如果简单的使用innerHTML添加元素,就有可能导致存在的元素刷新;

于是我们开始逐步分析。

显然,最先想到的就是匿名闭包的调用。

通常我们都是用:  (function(){})()  的形式调用一个匿名闭包。注意红色的优先级括号是必不可缺的,否则就是一个错误的语法。

但也可以使用另一种形式:+function(){}() 前面的+号可以换成-!~等等一元操作符。不过这仅仅是1字节之差。

另一个显然的,就是可以把void(0)的参数替换成闭包调用的表达式。void虽然只是个关键字,但有类似函数的功能,对于任何参数都返回undefined。如果没有void,在地址栏执行了javascript:后,页面就变成了脚本表达式返回值,大家应该都见过。

于是经过显而易见的观察,略微减少了3个字符。

javascript:void(+function(o){o.src='...';document.body.appendChild(o)}(document.createElement('script')))

不过上面都是浅层次的观察。现在我们来仔细的分析。

我们为什么要使用闭包,就是为了防止我们的变量和页面里的冲突。那么可以不使用变量吗?想要不出现变量,唯一办法就是使用链式的连等操作:利用 上个操作的返回值作为下个操作的参数。这段代码共有3个操作:创建脚本元素/脚本元素src赋值/添加脚本元素。仔细参考下W3C的手 册,DOM.appendChild不仅可以添加元素,并且返回值也是此元素。而src赋值和元素添加的顺序可以互换。因此我们可以用链式操作,从而彻底 告别闭包和变量:

javascript:void(document.body.appendChild(document.createElement('script')).src='...')

这一步,我们精简了19个字符!

我们继续观察。上面的代码里出现了2个document。我们如果用一个短变量代替的话又可以减少字数。但使用了变量的话又会出现冲突的问题, 于是又要用到闭包。。。仔细的回忆下,js里有个我们平时不推荐使用的东西:with。没错,使用他就可以解决这个问题。我是只需 with(document){…}即可。因为只有一行代码,所以那对大括号也可以去掉。于是又减少了4个字符:

javascript:with(document)void(body.appendChild(createElement('script')).src='...')

值得注意的是,void不再套在最外层了,因为with和if, for他们一样,不再是表达式,而是语句了。

此时,代码里的每句都是各司其责,连重复的单词都找不到了。我们还能否再精简?如果硬要找,那也只得从void这家伙身上找了。如果去掉它,那 地址栏执行后,页面就变成了脚本元素的src字符了。显然删不得。但我们可以尝试换个,比如alert。在对话框过后,页面仍保留着。

先前说了,void的功能仅仅是返回一个undefined,而alert没有返回值。这里就不得不说javascript与其他语言的不同之处了。在其他的语言里,几乎都有函数/过程这么两概念,过程就是没有返回值的函数。不过js可不同,在js里任何函数都有一个返回值,即使“ 没有返回值 ”也是一种返回值,他就是undefined。所以alert和void有着相同的返回值:undefined。只要地址栏执行后结果是它,页面就不会转跳,而其他诸如false,0,null,NaN等等都不行。

于是我们只需让表达式返回的是undefined就可以了,但必须比void()这几个字符短。要产生一个undefined,除了它字面常量 外,另外就是调用没有返回值的函数,或者访问一个对象不存在的属性。我们要尽可能简短。如果页面里使用了JQuery的话,我们用$.X就可以得到一个 undefined。但没用jq的话,就不能保证是否存在变量$了。既然找不到足够简短的全局变量,我们可以用json创造个匿名的,比如[]或{},然 后访问他的不存在属性,比如[].X。于是,我们可以告别void了:

javascript:with(document)body.appendChild(createElement('script')).src='...';[].X

这样就减少了1个字节。我们还可以合并下代码,用表达式替换X:

javascript:with(document)[][body.appendChild(createElement('script')).src='...']

这样又减少了1个字节。

事实上,js里的任何一个变量都是继承于Object的,即使数字也不例外。所以,我们完全可以用一个数字替换[],这样更进一步减少1个字符:

javascript:with(document)0[body.appendChild(createElement('script')).src='...']

到此,代码里除了src字符外,缩短到76字节。

当然,最终的极限仍在探索中。。。

配合Google的短域名服务Google URL Shortener,我们可以缩短脚本的URL,例如:

javascript:with(document)0[body.appendChild(createElement('script')).src='http://goo.gl/QPp29']

[转载]C#中不通过浏览页面直接登入博客园的实现

mikel阅读(1005)

[转载]【WINFORM】C#中不通过浏览页面直接登入博客园的实现 – 悠游人生 – 博客园.

在CSDN上看到了这个例子,觉得蛮好玩的,于是拿来改了一下。

这个例子有点像“三人行采集器”中的多用户自动登录功能或者是像许多浏览器中自动填表(填充账号、密码)功能。

即不通过浏览网页,直接由客户端程序来执行一些页面上的操作(如点击登入按钮,登入系统等)。

登入博客园:

1 private void wbCnblog_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
2 {
3 wbCnblog.ScriptErrorsSuppressed = true;
4
5 if ((e.Url.ToString().ToLower().Equals(http://passport.cnblogs.com/login.aspx)))   //博客园登陆页面
6 {
7 HtmlElement textboxUserId = this.wbCnblog.Document.GetElementById(tbUserName);
8 //如果没有ID,用 Name 获取
9 //HtmlElement textboxUserId = this.webBrowser1.Document.All[“登录用户名文本框的Name”];
10
11 HtmlElement textboxPassword = this.wbCnblog.Document.GetElementById(tbPassword);
12 //如果没有ID, 用Name 获取
13 //HtmlElement textboxPassword = this.webBrowser1.Document.All[“登录密码框的Name”];
14
15 HtmlElement buttonSubmit = this.wbCnblog.Document.GetElementById(btnLogin);
16 //如果没有ID, 用Name获取
17 //HtmlElement buttonSubmit = this.webBrowser1.Document.All[“登录按钮的Name”];
18
19 for (int i = this.listView_usr.SelectedItems.Count – 1; i >= 0; i–)
20 {
21 ListViewItem item = this.listView_usr.SelectedItems[i];
22 //this.listView_usr.Items.Remove(item);
23 string strUsr = item.SubItems[0].Text;
24 string strPwd = item.SubItems[1].Text;
25 textboxUserId.InnerText = strUsr;      //填写帐号
26 textboxPassword.InnerText = strPwd;   //填写密码
27 }
28
29
30 buttonSubmit.InvokeMember(click);               //触发提交按钮的点击事件登录博客园
31 }
32 }

登出博客园:

1 private void webBrowserQuit()
2 {
3 if (null == wbCnblog.Document)
4 {
5 return;
6 }
7
8 wbCnblog.Document.Cookie = “”;
9
10 HtmlElementCollection links = wbCnblog.Document.Links;
11 if (null == links)
12 {
13 return;
14 }
15
16 foreach (HtmlElement link in links)
17 {
18 if (null == link.InnerText)
19 {
20 continue;
21 }
22
23 if (link.InnerText.Equals(退出))
24 {
25 link.InvokeMember(click); //激发链接的点击事件
26 break;
27 }
28 }
29 }

代码: cnblogLogin.rar

刚才粗心大意,发图的时候竟然将自己密码给暴露出来了,无奈只能重新修改密码了

[转载]百度地图API详解之自定义地图类型

mikel阅读(1130)

[转载]百度地图API详解之自定义地图类型 – jz1108 – 博客园.

今天的文章主要介绍如何利用地图API实现自定义地图。

百度地图API目前默认支持两种地图类型(map type):普通图和三维图,它们分别通过常量BMAP_NORMAL_MAP和BMAP_PERSPECTIVE_MAP来表示,在1.2版本中这两个 常量实际上是MapType对象的实例。当然开发者也可以自己实例化一个MapType从而实现一个自定义的地图。

切图工具的使用

我们先从切图工具的使用开始,接着再分析该工具产生的代码来详细了解自定义地图的方法。切图工具放在了github上,具体地址为:https://github.com/jiazheng/BaiduMapTileCutter,进入后请下载TileCutter.exe:

注意,该工具是基于.NET平台开发的,所以要求有.NET Framework 4 以上的版本。

启动这个exe后会出现这个界面:

首先我们要做的就是选择一张图片作为地图的底图(图片下载自这里):

点击下一步后需要设置输出的目录,这里我们直接选择桌面:

继续下一步,这里要设置输出类型,我们使用默认值,即图块和相关代码都由工具生成:

坐标设置我们使用默认值,即图片的中心点所在的位置。由于我们制作的是独立的地图类型,所以中心点设置为0, 0即可。

级别范围设置:我们使用自定义,将范围设置为5到10级,原图放置在第10级,这样5到9级工具就会自动缩小图片。建议原图所在级别与最大级别一致,否则高于原图所在级别的时候图片会发虚(因为工具会将图片进行放大处理)。

设置地图类型的名称:

一切就绪,最后可以确认所有的信息是否正确。然后就可以点击“开始切图”了。

完成了:

这时我们会发现桌面多了一个index.html和一个tiles文件夹。我们打开index.html会看到结果:

源代码解析

现在再来看看这个页面的代码部分:

<!DOCTYPE html>
<html>
<head>
<title>自定义地图类型</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="http://api.map.baidu.com/api?v=1.2"></script>
</head>
<body>
<div id="map" style="width:800px;height:540px"></div>
<script type="text/javascript">
var tileLayer = new BMap.TileLayer();
tileLayer.getTilesUrl = function(tileCoord, zoom) {
    var x = tileCoord.x;
    var y = tileCoord.y;
    return 'tiles/' + zoom + '/tile' + x + '_' + y + '.png';
}
var MyMap = new BMap.MapType('MyMap', tileLayer, {minZoom: 5, maxZoom: 10});
var map = new BMap.Map('map', {mapType: MyMap});
map.addControl(new BMap.NavigationControl());
map.centerAndZoom(new BMap.Point(0, 0), 10);
</script>
</body>
</html>

代码先创建了一个TileLayer实例,它代表一个图层,接着实现getTilesUrl方法提供图片的路径。getTilesUrl方法由 API在铺图的时候进行调用,调用时会提供图块编号和级别信息,开发者要做的就是根据图块编号和级别信息返回正确图片地址(有关坐标和图块编号的内容可以 阅读此文)。

下面代码创建一个MapType实例,第一个参数为地图类型的名字,第二个参数为地图类型所对应的图层,这里我们直接传递之前创建的TileLayer实例,后面是一些可选的配置参数,这里指定了最小级别和最大级别。

后面的代码就很简单了,创建map实例,并通过配置参数指定地图类型为MyMap。

如果大家有月球或火星的图片,那么创建一个月球地图或者火星地图也就不是一件难事了。

[转载]C#串口通信总结

mikel阅读(969)

[转载]C#串口通信总结 – binfire – 博客园.

我们知道对于com组件,可以采用DllImport进行调用。例如:
[DllImport(KMY350X.dll)]
private static extern int OpenPort(int PortNum, int BaudRate);

如果一些厂家比较懒的话,没有提供相应的dll,我们只能对它进行串口通信编程了。以前从没接触过串口编程,最近在一个项目中有几个地方都需要采用串口通信,跟公司一个老手请教后,感觉学到了很多东西,特在此做个总结:

一:首先我们来认识下什么是串口:

右键 我的电脑-管理-设备管理器-端口,选择一个端口,点击属性。

我们可以看到该串口的属性,在C#中我们使用SerialPort类来表示串口

ConfigClass config = new ConfigClass();
comm.serialPort.PortName = config.ReadConfig(SendHealCard);
//波特率
comm.serialPort.BaudRate = 9600;
//数据位
comm.serialPort.DataBits = 8;
//两个停止位
comm.serialPort.StopBits = System.IO.Ports.StopBits.One;
//无奇偶校验位
comm.serialPort.Parity = System.IO.Ports.Parity.None;
comm.serialPort.ReadTimeout = 100;
comm.serialPort.WriteTimeout = –1;

二:串口调试工具:

在对串口进行编程时候,我们要向串口发送指令,然后我们解析串口返回的指令。在这里向大家推荐一款工具。

串口调试助手.exe

将要发送的指令用空格隔开,选择HEX显示为放回的字符串。

三:正式编程:

编写Comm类:

public class Comm
{
public delegate void EventHandle(byte[] readBuffer);
public event EventHandle DataReceived;

public SerialPort serialPort;
Thread thread;
volatile bool _keepReading;

public Comm()
{
serialPort = new SerialPort();
thread = null;
_keepReading = false;
}

public bool IsOpen
{
get
{
return serialPort.IsOpen;
}
}

private void StartReading()
{
if (!_keepReading)
{
_keepReading = true;
thread = new Thread(new ThreadStart(ReadPort));
thread.Start();
}
}

private void StopReading()
{
if (_keepReading)
{
_keepReading = false;
thread.Join();
thread = null;
}
}

private void ReadPort()
{
while (_keepReading)
{
if (serialPort.IsOpen)
{
int count = serialPort.BytesToRead;
if (count > 0)
{
byte[] readBuffer = new byte[count];
try
{
Application.DoEvents();
serialPort.Read(readBuffer, 0, count);
if(DataReceived != null)
DataReceived(readBuffer);
Thread.Sleep(100);
}
catch (TimeoutException)
{
}
}
}
}
}

public void Open()
{
Close();
serialPort.Open();
if (serialPort.IsOpen)
{
StartReading();
}
else
{
MessageBox.Show(串口打开失败!);
}
}

public void Close()
{
StopReading();
serialPort.Close();
}

public void WritePort(byte[] send, int offSet, int count)
{
if (IsOpen)
{
serialPort.Write(send, offSet, count);
}
}
}

注册串口:

Comm comm = new Comm();
ConfigClass config = new ConfigClass();
comm.serialPort.PortName = config.ReadConfig(SendHealCard);
//波特率
comm.serialPort.BaudRate = 9600;
//数据位
comm.serialPort.DataBits = 8;
//两个停止位
comm.serialPort.StopBits = System.IO.Ports.StopBits.One;
//无奇偶校验位
comm.serialPort.Parity = System.IO.Ports.Parity.None;
comm.serialPort.ReadTimeout = 100;
comm.serialPort.WriteTimeout = –1;

comm.Open();
if (comm.IsOpen)
{
comm.DataReceived += new Comm.EventHandle(comm_DataReceived);
}

发送指令:

/// <summary>
/// 发卡到机口
/// </summary>
private void SendCardToOut()
{
is_read_card = false;
sendCardToOut = true;
byte[] send = { 0x020x460x430x340x030x30 };
if (comm.IsOpen)
{
comm.WritePort(send, 0, send.Length);
}
}


收到指令,并解析:

void comm_DataReceived(byte[] readBuffer1)
{
//log.Info(HexCon.ByteToString(readBuffer));
if (readBuffer1.Length == 1)
{
receive = HealCardClass.ByteToString(readBuffer1);
string str = 06;
if (string.Equals(receive.Trim(), str, StringComparison.CurrentCultureIgnoreCase))
{
try
{
if (is_read_card)
{
byte[] send = new byte[1];
send[0] = 0x05;
comm.WritePort(send, 0, send.Length);
Thread.Sleep(500);
comm.DataReceived -= new Comm.EventHandle(comm_DataReceived);
InitReadComm();
}
if (sendCardToOut)
{
byte[] send = new byte[1];
send[0] = 0x05;
comm.WritePort(send, 0, send.Length);

readComm.DataReceived -= new Comm.EventHandle(readComm_DataReceived);
readComm.Close();

log.Info(发卡完成!);
lblMsg.Text = 发卡成功!;
lblSendCardMsg.Text = 发卡完成,请收好卡!;
timer1.Tick -= new EventHandler(timer1_Tick);
PlaySound();
this.btnOK.Enabled = true;

}
}
catch (Exception ex)
{
log.Info(ex.ToString());
}
}
}
}


至此,串口通信编程告一段落

[转载]在线网站压力测试|看看你的网站能承受多少人同时在线

mikel阅读(930)

[转载]在线网站压力测试|看看你的网站能承受多少人同时在线 | 踢扑网—在线制作类网站推荐!.

踢扑网今天推荐一款比较适合个人网站站长使用的在线测试网站压力的在线工具《LoadImpact》,如果你想了解你的网站能够在10人。20人。 50人,甚至5000人同时在线的情况下,网站是否会因为同时在线人数过多而影响网站的响应速度,从而了解自己网站的最大负载。该网站测试的标准有两种, 一种是普通的免费测试,只支持10人,20人,30人,40人,50人同时在线的模拟测试。另一种是最大支持5000人同时在线的收费测试,当然,建议大 家使用免费的测试玩玩。

使用方法很简单,进入网站首页,在网址输入框输入您要测试的网站的URL,然后按开始测试。整个过程大概需要20分钟以上,这个过程您可以做点其他的事,等测试结束后再回头看看测试结果就行了。

【网站名称】

LoadImpact

【网站地址】猛击这里

0

[转载]ASP.NET MVC3实践--入门

mikel阅读(890)

[转载]ASP.NET MVC3实践–入门 – 午夜凋零 – 博客园.

1、引言

MVC3是ASP.NET框架下的MVC框架,随MVC3同期发布的还有ASP.NET的最新引擎Razor,关于MVC3和Razor的详细文档参见MSDN

MSDN:MVC3 MSDN上的MVC3参考,建议快速浏览

MSDN:Razor Razor的整体介绍,建议未使用过的读者详细了解下

本博客从本文开始,将陆续推出ASP.NET MVC3的系列文章,旨在介绍ASP.NET的MVC框架,以及如何利用此框架进行高效的WEB开发。对于本文的读者,需要了解ASP.NET、MVC构 架、以及Entity Framework的基础知识。好的,废话不多说,让我们开始ASP.NET的MVC之旅吧!

2、ASP.NET框架下的MVC应用程序的执行

阶段 详细信息
接收对应用程序的第一个请求 在 Global.asax 文件中,Route 对象将添加到 RouteTable 对象中。
执行路由 UrlRoutingModule 模块使用 RouteTable 集合中第一个匹配的 Route 对象来创建 RouteData 对象,然后使用所创建的对象创建 RequestContext 对象。
创建 MVC 请求处理程序 MvcRouteHandler 对象将创建 MvcHandler 类的实例,并将 RequestContext 实例传递给处理程序。
创建控制器 MvcHandler 对象使用 RequestContext 实例标识用于创建控制器实例的 IControllerFactory 对象(通常是 DefaultControllerFactory 类的实例)。
执行控制器 MvcHandler 实例调用控制器的 Execute 方法。
调用操作 对于从 ControllerBase 类继承的控制器,与该控制器关联的 ControllerActionInvoker 对象将决定要调用的 controller 类的操作方法,然后调用该方法。
执行结果 操作方法将接收用户输入,准备合适的响应数据,然后通过返回结果类型来执行结果。 可执行的内置结果类型包括:ViewResult(呈现视图并且是最常用的结果类型)、RedirectToRouteResultRedirectResultContentResultJsonResultFileResult 和 EmptyResult



3、开发环境

Visual Studio 2010的安装包只包含MVC2,需要单独安装,建议使用http://www.asp.net/mvc/mvc3上的web installer安装,如果使用单独的ASP.NET MVC3安装包,可能在个别步骤出现挂起的现象。

数据库方面,为了方便使用Entity Framwork,本文使用SQL Server。配置方面不用过多关注,只需要默认配置就能够运行本文提供的内容。

与J2EE框架下的MVC繁琐的开发环境搭建不同,在ASP.NET下,只需要如下工具即可:

Visual Studio Web Developer Express 2010

ASP.NET MVC 3 Tools

SQL Server 2008 Express

下面的链接有asp.net站点提供的Web Developer Express+MVC3的web installer。

http://www.asp.net/mvc/mvc3

不过对于有条件的读者,建议使用Visual Studio的完整版本。


4、辅助工具NuGet

NuGet是.NET平台下面向开发者的包管理器,对于曾经挣扎在Struts、Hibernate等东西的配置文件的读者来说,NuGet是 一开发者的福音。NuGet的使用类似于Linux下的包管理器,但也许更为简单。对于一个项目,NuGet可以做下面这些事情:

1. 搜索包;

2. 下载包到本地并添加到项目中(包括添加引用和dll等文件);

3. 根据包自动配置Web项目的config文件。

关于NuGet的更多内容,请参考codeplex上的NuGet项目:

http://nuget.codeplex.com/

这里,我们演示如何使用NuGet在一个空MVC3项目中加入Ajax Control Toolkit,这将是一个非常简单的过程^_^。

首先新建一个MVC3项目,选择空模板,Project Layout如图1所示:

图1.

然后,右键单击项目中的“引用”,在弹出菜单中点击“Manage NuGet Packages”,在搜索框中键入要搜索包的名字即可,如图2所示:

图2.

然后点击Install,然后,就没有然后了,NuGet会为你完成所有的配置!

Tips:MVC3的项目模板,包括Empty的模板,会安装如EntityFramework、JQuery等几个常用的包,这些包都可以使用NuGet来进行管理。

[转载]ASP.NET MVC3实践--一个简单的MVC3应用

mikel阅读(1031)

[转载]ASP.NET MVC3实践–Movie,一个简单的MVC3应用 – 午夜凋零 – 博客园.

作为本系列的第一个应用,本文选取了ASP.NET上的一个tutorial project,“movie list”作为例子,由于本系列面向的是对ASP.NET以及mvc开发有一定基础的读者,除razor相关内容外,均从简介绍。

1、创建工程

选择C#的Web项目,创建一个MVC3项目,如图1.,我们使用第二个模板,并确保其中的View Engine为Razor,并勾选HTML5语法标签。

图1.

创建好项目之后,Project Layout如图2所示,请记住这个Layout,这是一个典型的MVC3项目的布局。

图2.

对于使用过MVC2的读者来说,相信对_ViewStart和_Layout两个文件不会陌生,关于ASP.NET MVC框架的其他细节,请参考:

MSDN:MVC3 MSDN上的MVC3参考,建议快速浏览

MSDN:Razor Razor的整体介绍,建议未使用过的读者详细了解下

ASP.NET MVC3实践–入门

2、观察和修改HomeController

打开HomeController.cs,我们修改其中的ViewBag.Message内容,如图3所示。这里我们将第一次接触到Razor,并 且一上来就是非常强大的一个内容,ViewBag。这是一个动态类型,可以动态的设置一个具有get/set方法的属性,简单的说就是,你可以给 ViewBag添加你想要的信息,比如ViewBag.LoveMessage、ViewBag.Eureka等等。这里我们给ViewBag附加一个 Eureka属性(不要问我Eureka是什么……⊙﹏⊙b),然后给其赋值为:“My Movie List”。

图3.

注意,我们这里使用的是MVC模板提供的HomeController,我们修改了模板预先设的ViewBag.Message,由于 ViewBag.Message在Index的View中被应用了,因此,我们需要修改View中的引用,如图4所示。这里我们见到了Razor的有一个 及其方便的功能,“@”符号,由“@”引导的语句,Razor引擎会将其解析为C#代码,“@{//code block}”则可以支持代码段。作为尖括号写到吐的Web开发人员,这无疑又是一个非常好的改进。

图4.

好了,这时候,让我们编译项目,然后看看我们的第一个MVC3应用吧,run it!如图5所示

图5.

3、创建一个我们自己的Controller并为其View。

细心的读者可能会发现,我们前面的HomeController中,注释掉了About方法。是的,在这一步开始之前,你需要注释掉 HomeController中的About的方法,并删除View中Home目录下的About.cshtml。好的,我们开始创建 Controller,右键单击Controller文件夹,选择添加->Controller,创建一个名为About的Controller, 这里使用Empty模板,我们暂时还不需要它做更多的事情。

图6.

之后我们将得到一个AboutController类,如图7所示。有了Controller,我们自然会想到View(注意,这里我们不需要 About做更多的事,所以我们不需要Model),要添加View,在Visual Studio中是一件再简单不过的事情了,右键点击方法,选择Add View,Visual Studio就会为我们生成对应方法的View了。

图7.

我们在生成的View中稍作显示内容的修改,如图8所示

图8.

这里再次强调,我们使用的事Visual Studio提供的项目模板,我们删除了HomeController中的About方法及其View,但是还没有修改About的链接,注意,模板中在 Layout里面有About的链接。我们修改原ActionLink的ActionName和Controller为我们的 AboutController的Index方法和新的Controller名字,About。

图9.

好的,修改完成,我们来看看我们的成果吧。

图10.

4、使用EntityFramework的Code First创建一个Model,并为其创建Controller和View。

再次强调,本文面向有一定ASP.NET基础的读者,如果你有Hibernate的变成经验,也可以。关于Code First,本文以及后续文章都不会做详细介绍,但是会有大量例子。所谓Code First,义如其名,先有Code在有其他,换句话说,先写了数据实体的类,然后数据库什么的,EntityFramework会为我们搞定。Code First属于EntityFramework中的一种模式,其他的有Schema First和Model First。

首先,在Models文件夹中添加一个类,命名为Movie,如图11所示

图11.

Tips:许多Visual Studio的使用者并不熟悉Visual Studio的操作细节,比如这里我们要为Moive创建5个属性,在创建每个属性前,我们只需要键入“prop”然后按两次tab建,即可生成一行public属性模板。

然后,我们创建一个Context,最简单的Code First,我们的数据库就建好了!

图12.

再有了数据的code之后,我们只需要在根目录)的web.config中添加connectionString,后台的数据处理EntityFramwork会为我们完成(相信有Hibernate开发经验的读者很容易理解这一点)

需要注意的是,connectionString需要设置name属性为之前创建的Context属性:

<add name="MovieDbContext"
connectionString="data source=.\SQLexpress;integrated security=SSPI;database=Movie"
providerName="System.Data.SQLClient"/>

Model已经有了,MVC还差V和C,这里我们不在手动添加V和C了,而是使用Visual Studio的强大自动化功能,右键单击Controllers文件夹,添加一个Controller,这里,如图13所示。

Template:具有read/write/view方法的Controller

Model class:Movie

Data context class:MovieDbContext

并确保使用Razor引擎。

图13.

然后点击Add,Visual Studio便会为我们自动创建Movie这个Model的Controller和View了。Movies的代码如代码段所示,可以看到,出了 Index方法,Visual Studio还自动创建了数个其他的方法,并且,其中部分还有GET和POST两个版本。

关于MVC的细节,这里不做详述。接下来,我们看一看系统为我们创建了那些View,如图14所示,

图14.

这里我们来看其中一个View的内容的一段。

图15.

关于这段代码,细心的读者会发现,这简直太犀利了,Html和C# Code竟然如此完美的无缝结合在一起!关于更多的细节,我将在后续文章中为大家带来。

好的,最后,我们来看看我们的最终成果吧(这里,我使用Create New创建了了两条栏目)。

图16.

这就是Razor,这就是ASP.NET MVC3!


本文涉及到的代码下载

为了避免兼容性问题,这里只提供改动了的文件,如需使用,只需按本文前面所述的步骤创建工程,然后将包中内容覆盖之即可,后续文章的下载也同样如此。

[转载]基于RBAC模型的通用企业权限管理系统

mikel阅读(955)

[转载]基于RBAC模型的通用企业权限管理系统 – 至软 – 博客园.

1. 为什么我们需要基于RBAC模型的通用企业权限管理系统

管理信息系统是一个复杂的人机交互系统,其中每个具体 环节都可能受到安全威胁。构建强健的权限管理系统,保证管理信息系统的安全性是十分重要的。权限管理系统是管理信息系统中代码重用性最高的模块之一。任何 多用户的系统都不可避免的涉及到相同的权限需求,都需要解决实体鉴别、数据保密性、数据完整性、抗否认和访问控制等安全服务(据ISO7498-2)。例 如,访问控制服务要求系统根据操作者已经设定的操作权限,控制操作者可以访问哪些资源,以及确定对资源如何进行操作。

目前,权限管理系统也是重复开发率最高的模块之一。在企业中,不同的应用系统都拥有一套独立的权限管理系统。每套权限管理系统只满足自身系统的权限管理需要,无论在数据存储、权限访问和权限控制机制等方面都可能不一样,这种不一致存在如下弊端:

l 系统管理员需要维护多套权限管理系统,重复劳动。

l 用户管理、组织机构等数据重复维护,数据一致性、完整性得不到保证。

l 由于权限管理系统的设计不同,概念解释不同,采用的技术有差异,权限管理系统之间的集成存在问题,实现单点登录难度十分大,也给企业构建企业门户带来困难。

采用统一的安全管理设计思想,规范化设计和先进的技术架构体系,构建一个通用的、完善的、安全的、易于管理的、有良好的可移植性和扩展性的权限管理系统,使得权限管理系统真正成为权限控制的核心,在维护系统安全方面发挥重要的作用,是十分必要的。

2. 我们需要了解哪些知识点

2.1. RBAC模型

标准RBAC模型由4个部件模型组成,这4个部件模型 分别是基本模型RBAC0(Core RBAC)、角色分级模型RBAC1(Hierarchal RBAC)、角色限制模型RBAC2(Constraint RBAC)和统一模型RBAC3(Combines RBAC)

a. RBAC0定义了能构成一个RBAC控制系统的最小的元素集合。在RBAC之中,包含用户users(USERS)、角色roles(ROLES)、目标 objects(OBS)、操作operations(OPS)、许可权permissions(PRMS)五个基本数据元素,权限被赋予角色,而不是用 户,当一个角色被指定给一个用户时,此用户就拥有了该角色所包含的权限。会话sessions是用户与激活的角色集合之间的映射。RBAC0与传统访问控 制的差别在于增加一层间接性带来了灵活性,RBAC1、RBAC2、RBAC3都是先后在RBAC0上的扩展。

b. RBAC1引入角色间的继承关系,角色间的继承关系可分为一般继承关系和受限继承关系。一般继承关系仅要求角色继承关系是一个绝对偏序关系,允许角色间的多继承。而受限继承关系则进一步要求角色继承关系是一个树结构。

c. RBAC2模型中添加了责任分离关系。RBAC2的约束规定了权限被赋予角色时,或角色被赋予用户时,以及当用户在某一时刻激活一个角色时所应遵循的强制 性规则。责任分离包括静态责任分离和动态责任分离。约束与用户-角色-权限关系一起决定了RBAC2模型中用户的访问许可。

d. RBAC3包含了RBAC1和RBAC2,既提供了角色间的继承关系,又提供了责任分离关系。

2.2. 组织机构

企业组织架构包含三个方面的内容:单位、部门和岗位。 一个单位可以设置多个部门,部门是组成单位的部分。一个部门可以设置多个岗位,岗位是职工职务、工作任务和责任、权限的统一。一个部门只能设定一个部门主 管岗位,一个岗位可以由多个员工担任,员工是指机构中各种用工形式的人员。

相关术语

l 任务 是为了达到某一特定目标或者完成领导交待的工作而进行的一项活动。

l 职务 指对职工所应承担事务的规定。它与职位的不同点在于强调所承担的任务内容,而不是指任务的地点。

l 责任 指份内应做的事。即职工在职务规定的范围内应尽责尽职、保质保量地完成任务。

l 职责 职务和责任的统一。专指须有一名职工担负的各项任务组成的工作活动。

3. 我们怎么设计基于RBAC模型的通用企业权限管理系统

根据RBAC模型的权限设计思想,建立权限管理系统的 核心对象模型。对象模型中包含的基本元素主要有:组织机构(Organization)、部门(Department)、岗位(Post)、用户 (User)、角色(Role)、系统功能(Function)、权限(Permission)。主要的关系有:分配角色权限PA(Permission Assignment)、分配用户角色UA(User Assignmen),具体描述如下:

a. 组织机构:使用系统的主体。

b. 部门:是组成单位的部分。

c. 岗位:是职工职务、工作任务和责任、权限的统一。

d. 用户:是权限的拥有者或主体。用户和权限实现分离,通过授权管理进行绑定。

e. 角色:权限分配的单位与载体。角色通过继承关系支持分级的权限实现。例如,科长角色同时具有科长角色、科内不同业务人员角色。

f. 系统功能:是系统所要保护的资源(Resource),可以被访问的对象。

g. 权限:对受保护的资源操作的访问许可(Access Permission),是绑定在特定的资源实例上的。

h. 分配角色权限PA:实现操作和角色之间的关联关系映射。

i. 分配用户角色UA:实现用户和角色之间的关联关系映射。

我们对元素之间的关系作如下限制:

a. 一个单位可以设置多个部门

b. 一个部门可以设置多个岗位

c. 一个部门只能设定一个部门主管岗位

d. 一个岗位可以由多个员工担任

e. 一人员工担任多个岗位

f. 一个用户可以拥有多个角色

g. 一个角色可以由多个用户拥有

h. 系统功能与角色之间设置权限访问许可

i. 系统功能通过资源来限制访问

对象模型图如下:

clip_image002

4. 优缺点

4.1. 缺点

具体授权的方法必须通过不同的资源方法来实现控制,相对通用性比较差。

[转载]用python提取百度贴吧的小说

mikel阅读(1009)

[转载]用python提取百度贴吧的小说 – ToddNet2012 – 博客园.

这个博客主要是发表些关于Windows Phone开发相关方面的文章的,和 http://blog.sina.com.cn/u/2391033251 同 步更新。不过今天不务正业一下,发表一段python代码。这个程序主要功能是从百度贴吧,获得html文件,然后用Beautiful Soup解析html文件,提取贴吧的帖子。干什么的?其实是来看小说的,想做的更自动化一些的,但是python开始学没多长时间,暂时做到这个程度 了,以后有机会会考虑增强功能的。

代码如下:

#-*- encoding: utf-8 -*-
import urllib2
import re
from BeautifulSoup import BeautifulSoup

def stripHTMLTags (html):
'''strip html tags; from http://goo.gl/EaYp5'''
return re.sub('&lt;([^!&gt;]([^&gt;]|\n)*)&gt;', '', html)

def fetch_tieba(url,localfile,ignoreFansReq=False):
'''fetch the url resource and save to localfile'''

# fetch the url resource and encode to utf-8
html = urllib2.urlopen(url).read()
html = unicode(html,'gb2312','ignore').encode('utf-8','ignore')

# extract the main content
content = BeautifulSoup(html).findAll(attrs={'class':'d_post_content'})

# write the content to localfile
myfile = open(localfile,'w')
for item in content:
item_formatted = stripHTMLTags(str(item).replace('
','\r\n'))
if ignoreFansReq == True :
if len(item_formatted) &lt; 100:
continue
myfile.write(item_formatted)
myfile.write('\r\n')
print item_formatted
myfile.close()

def main():
urlTarget = "http://tieba.baidu.com/p/1234371208"
localfileTarget = './xiaoshuo2.txt'
fetch_tieba(url=urlTarget,localfile=localfileTarget,ignoreFansReq=True)

if __name__ == "__main__":
main()

简单说明:
1 本人使用的开发环境是 Windows 7 Ultimate 32bit + Python 2.7;依赖 Beautiful Soup (地址) ,使用版本是 BeautifulSoup-3.2.0;
2 fetch_tieba函数参数的含义:url,贴吧资源目标地址;localfile,保存到本地文件的路径;ignoreFansReq,忽略插楼、求粉等灌水信息(只是根据文字数判断,很简陋);
3 代码具有时效性,如果百度贴吧的页面DOM发生改变,程序可能失效。

[转载]Android中解析json方法

mikel阅读(938)

[转载]解析json – penink – 博客园.

关于Jsonhttp://www.json.org/

Json解析库gson: http://code.google.com/p/google-gson/

1.使用Android中的JSONObjectJSONArray解析json数据

String strJson = "{\"students\":[{\"name\":\"Jack\",\"age\":12}, {\"name\":\"Vista\",\"age\":23}, {\"name\":\"Kaka\",\"age\":22}, {\"name\":\"Hony\",\"age\":31}]}";
try {
JSONObject jo = new JSONObject(strJson);
JSONArray jsonArray = (JSONArray) jo.get("students");
for (int i = 0; i &lt; jsonArray.length(); ++i) {
JSONObject o = (JSONObject) jsonArray.get(i);
System.out.println("name:" + o.getString("name") + "," + "age:"
+ o.getInt("age"));
}
} catch (JSONException e) {
e.printStackTrace();
}

2.使用gson中的JsonReader解析json数据

try {
String string = "{\"class\":1, \"students\":[{\"name\":\"jack\", \"age\":21},{\"name\":\"kaka\", \"age\":21},{\"name\":\"lucy\", \"age\":21}]}";
StringReader sr = new StringReader(string);
JsonReader jr = new JsonReader(sr);
jr.beginObject();
if (jr.nextName().contains("class")) {
System.out.println("班级: " + jr.nextString());
if (jr.nextName().equals("students")) {
jr.beginArray();
while (jr.hasNext()) {
jr.beginObject();
if (jr.nextName().equals("name"))
System.out.print("姓名:" + jr.nextString());
if (jr.nextName().equals("age")) {
System.out.println(" , 年龄:" + jr.nextInt());
}
jr.endObject();
}
jr.endArray();
}
}
jr.endObject();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}