[MVC]ASP.NET MVC实践系列11-FCKEditor和CKEditor的使用

mikel阅读(534)

转载:http://www.cnblogs.com/nuaalfm/archive/2009/11/27/1612027.html

FCKEditor是一款强大的在线编辑器,简单实用,多浏览器兼容,免费开源,应用十分广泛,据他的官方网站上称有三百多万的下载量,而且无数的 知名大公司正在使用它。所以FCKEditor是很值得信赖的,现在 FCKeditor项目已转向下一代版本命名CKEditor的产品开发,基本上采用Fckeditor并对部分进行了重新设计和采用新技术以改善结构, 性能更好扩展性更强。下面我们来介绍一个这两个编辑器,对于FCKEditor我们只讲一下在ASP.NET MVC中的用法其配置可以参考官方文档。

一、FCKEditor使用:

1、FCKEditor在ASP.NET MVC中的应用:

首先到http://ckeditor.com/download下载FCKeditor 2.6.5(我下载的时候报地址暂时有问题,但FCKEditor网上保有量很多,可以任意下载一个),将下载好的文件解压缩然后拷贝到你项目的Content文件夹下:

View

 

View代码

Controller:

 

Controller

 1 [AcceptVerbs(HttpVerbs.Post)]
 2         [ValidateInput(false)]
 3         public ActionResult Test(string FckEditor1)
 4         {
 5             this.ValidateRequest = false;
 6             return Content(FckEditor1);
 7         }
 8         public ActionResult Test()
 9         {
10             return View();
11         }

 

 这里要注意[ValidateInput(false)]特性,它的目的是为了防止在提交时报“检测到有潜在危险的客户端输入值”,另外这里还有 个奇怪的现象就是这个View不能在Index.aspx中,在Index.aspx即使使用了[ValidateInput(false)]特性还是会 报错,换个新View就没这个问题了,不知道为什么?

2、Helper版

为了让大家使用的更简单,我写了个Helper版,大家参考下:

 

Helper

View:

 

代码

<script src="<%= Url.Content("~/Content/fckeditor/fckeditor.js") %>" type="text/javascript"></script>
     
<%=Html.FckEditor(Url.Content("~/Content/fckeditor/"), "lfm"new { x = "x" })%>

 

二、CKEditor使用

1、CKEditor在ASP.NET MVC中的应用:

首先到http://ckeditor.com/download下载CKEditor。

CKEditor在ASP.NET MVC的使用就相当的简单了,只需要在脚本中执行CKEDITOR.replace(id);id为你需要拥有编辑功能的textarea的id。

View:

 

代码

     <script src="<%= Url.Content("~/Content/ckeditor/ckeditor.js") %>" type="text/javascript"></script>
    
<% using (Html.BeginForm())
       { 
%>
    
<%= Html.TextArea("ckEditor1""Some Value",   new { @name="ckEditor1" })%>
    
<input type="submit" value="提交" />
    <% } %>
    
<p>
    
</p>

        
<script type="text/javascript">
            CKEDITOR.replace(
'ckEditor1');
     
</script>

结果:

 

2、CKEditor配置:

CKEditor配置也很容易, 使用CKEDITOR.replace方法,根据不同的参数来应用不同的配置,例如

 

代码

<script type="text/javascript">
     CKEDITOR.replace( 
'editor2',
      {
       extraPlugins : 
'uicolor',
       uiColor: 
'#14B8C4',
       toolbar :
       [
        [ 
'Bold''Italic''''NumberedList''BulletedList''''Link''Unlink' ],
        [ 
'UIColor' ]
       ]
      } );
    
</script>

得到的结果:

其他配置可以参考官方文档。同时_samples文件夹中也有大量例子可供参考。

3、CKEditor瘦身:

如果你觉得整个编辑器太大,你可以删除文件。

例如把_samples、_source、文件夹删除,进入lang文件目录,保留en.js、zh.js、zh-cn.js三个文件,其余的语言文件如果你用不到,可以删除。

三、参考

http://www.ff-bb.cn/logs/46479725.html

http://www.codeproject.com/KB/aspnet/fckeditor.aspx

 

我的ASP.NET MVC实践系列

ASP.NET MVC实践系列1-UrlRouting

ASP.NET MVC实践系列2-简单应用

ASP.NET MVC实践系列3-服务器端数据验证

ASP.NET MVC实践系列4-Ajax应用

ASP.NET MVC实践系列5-结合JQuery

ASP.NET MVC实践系列6-Grid实现(上)

ASP.NET MVC实践系列7-Grid实现(下-利用Contrib实现)

ASP.NET MVC实践系列8-对查询后分页处理的解决方案

ASP.NET MVC实践系列9-filter原理与实践

ASP.NET MVC实践系列10-单元测试

其他:

在ASP.NET MVC中对表进行通用的增删改

[MVC]ASP.NET MVC实践系列10-单元测试

mikel阅读(556)

转载:http://www.cnblogs.com/nuaalfm/archive/2009/11/26/1611420.html

最早接触单元测试是看了极限编程相关资料里边讲的测试驱动开发,然后下载了Nunit研究了一下,但并没产生多大的触动,因为那个时候做的都是些时 间紧任务重的事情,对于单元测试的直接感觉就是有可能比较费时间。直到看了《敏捷软件开发:原则、模式与实践》,里边那个保龄球计分程序很精彩,让我知道 了保龄球原来是这么计分的,更重要的是让我认识到测试驱动编程原来这样有意义,并且其实并不浪费时间(至于测试驱动编程到底有意义在哪里,我这里就不说 了,大家可以参阅Kent的《测试驱动开发》,Robert C. Martin的《敏捷软件开发:原则、模式与实践》,http://www.ibm.com/developerworks/cn/linux/l-tdd/http://www.ibm.com/developerworks/cn/java/j-xp042203/等)。在webform中对web层的逻辑很难做单元测试(当然我们可以利用mvp模式(参考:http://www.cnblogs.com/bluewater/archive/2006/12/11/589214.html#1219888) 来分解web层逻辑,但因为没有框架的支持,并且实现起来也不是很简单,也不是特别好理解,所以应用并不广泛)。ASP.NET MVC很好的解决了测试web逻辑的问题,可测试性也变成了ASP.NET MVC的优势之一。下面我们就来介绍一下如何在ASP.NET MVC中进行单元测试。

一、测试路由器:

我们首先利用mvc的模板创建一个解决方案,我们可以在Gloabal.asax.cs文件中发现如下代码

 

默认路由代码

 

下面我们就为这段代码写一个单元测试(如果对路由还不清楚请参见:ASP.NET MVC实践系列1-UrlRouting

 

测试代码

 

下面我们解释一下上面的代码

RouteCollection routes = new RouteCollection();
MvcApplication.RegisterRoutes(routes);

这两行的意思是将routes按照默认路由代码中的格式生成相应的路由。

var httpContextMock = new Mock<HttpContextBase>();
httpContextMock.Setup(c => c.Request.AppRelativeCurrentExecutionFilePath).Returns("~/Home/Index");

这两行的意思是创建一个HttpContextBase的mock类,这里我们使用的是MoQ框架来生成mock类(参见:MoQ(基于.net3.5,C#3.0的mock框架)简单介绍 )。

RouteData routeData = routes.GetRouteData(httpContextMock.Object);

这行的意思是从routes中获得路由数据,为下边断言路由中的内容作准备。

Assert.AreEqual("Home", routeData.Values["Controller"]);
Assert.AreEqual("Index", routeData.Values["action"]);
Assert.AreEqual("", routeData.Values["id"]);

这三行分别验证了路由中生成的Controller,action,id的正确性。

二、测试Controller与Action

1、测试ViewData

我们先来看一下ASP.NET MVC的默认模板中的测试代码:

 

Code

 

我们可以在测试代码中对viewData的内容进行验证,一般并不推荐使用弱类型的viewData来进行传递数据,下面我们来看一下如何来测试viewModel中的内容。

 

Code

 

2、测试RedirectToAction:

 

Code

 

三、测试View Helpers

我们常常会把一些牵扯到逻辑的View代码写到Helper中,所以测试Helper非常有意义,我们先写一个简单的Helper

 

Helper

 

这个Helper的完成的工作是将输入的集合数据分解然后按列表输出。

 

测试代码

 

4-9行都是为实例化HtmlHelper做准备的。

四、参考

《Professional ASP.NET MVC 1.0》

《ProASP.NET MVCFramework》

http://msdn.microsoft.com/en-us/magazine/dd942838.aspx

http://www.henrycordes.nl/post/2008/02/MVC-Framework-and-Unit-Test.aspx

http://srtsolutions.com/blogs/patricksteele/archive/2009/08/23/asp-net-mvc-mvc-contrib-unit-testing.aspx

http://weblogs.asp.net/leftslipper/archive/2008/04/13/mvc-unit-testing-controller-actions-that-use-tempdata.aspx

 

 

我的ASP.NET MVC实践系列

ASP.NET MVC实践系列1-UrlRouting

ASP.NET MVC实践系列2-简单应用

ASP.NET MVC实践系列3-服务器端数据验证

ASP.NET MVC实践系列4-Ajax应用

ASP.NET MVC实践系列5-结合JQuery

ASP.NET MVC实践系列6-Grid实现(上)

ASP.NET MVC实践系列7-Grid实现(下-利用Contrib实现)

ASP.NET MVC实践系列8-对查询后分页处理的解决方案

ASP.NET MVC实践系列9-filter原理与实践

其他:

在ASP.NET MVC中对表进行通用的增删改

[SEO]被搜索引擎省略了相似内容的条目该怎么办?

mikel阅读(769)

转载:http://www.SEOwindows.com/SEOjq/200908/135.html

我们常常在GOOGLE或百度中用site指令的时候,会发现在结果最底部会出现“……我们省略了一些内容相似的条目,点击这里可以看到所有搜索结果”。

为什么会出现这种情况呢,最大可能就是被隐藏网页的相似度太高。

之前GOOGLE存在“补充材料”的时候,相似页面就很容易被Google贴上“补充材料”的标签。“补充材料”页的产生还有其他方面的因素,例如描述等。只不过,相似页面也是因素之一。

相似页面的优化,在SEO优化的工作当中,也是一个需要注意的细节。相似页面的清理和优化,可能主要涉及到网页设计人员。相似页面的产生,主要是因为这类页面的主体内容比较少,一些比较常规的辅助内容比较多。从而形成相似页面,这类页面在搜索引擎看来,价值性不高。

相似页面在网站整体的网页结构当中,可能是处在网页价值的末端。就是不太重要的网页,也很难获得搜索引擎的排名。

相似页面的形成

在每个网页中,正文内容必须在网页全部内容当中,占据比较重要或者比较大的比例。一般来说,正文在整张网页当中,所占比例只有20%-30%的时候,那很容易就形成一张相似页面。

主体内容在网页中的重要性

网页的正文就是网页的核心内容,网站管理者不应该为了更新网站或者方便,随便的写几句话就作为网站的原创内容来更新到网站。

网页的正文内容,文字不应该少于500字。字数太少,搜索引擎分析出网页的主题。分析不出网页主题,也就不利于网页的搜索引擎排名

相似页面对网站的影响

相似页面过多的话,会稀释网站质量,包括权重、PR、链接等。从而影响到网站整体在搜索引擎上的表现,例如长尾关键词的排名表现的不理想等。比较严重的惩罚是认为网站管理员有SEOSPAM行为,对此类网页给予不收录或者降权等。

如何优化相似页面:

1.防止正文内容过少,这是最好防止产生相似页面的技巧之一;

2.让搜索引擎的蜘蛛优先抓到正文;

3.减少网页中不必要的内容结构。

网站内部优化其实就是把不必要的东西去除或者改善不好的内容。在网站优化中,应该尽量避免出现过多的相似页面。大家日常的更新网站内容的时候应该注意内容篇幅,看看正文是否能够说明页面主题。

[SEO]反向链接的四大原则

mikel阅读(640)

转载:http://www.joyinweb.cn/html/baidu/2009/0922/826.html
反向链接是百度优化里常提到的说法,是SEO的第二要素,大多非专业人士可能不太熟悉,反向链接的一些指标也反应网站的健康状况,下面详细认识一下反向链接。
       一、反向链接的定义

      反向链接英文是:BackLinks,或Back-Links,又称为导入链接(incominglinks)。反向链接其实就是在目标文档内部进行声 明。换言之,常规链接在文档A中标明“指向文档B”,而反向链接则在文档B中要求“使文档A指向我”。反向链接是SEO的第二要素,重要性毋庸置疑。网络 上流传很多增加反向链接的10种方法、66种方法、101种方法,更有很多群建、群发的“黑帽”软件在流传,这里不做过多讨论。

    二、反向链接的原则

    1、时间原则

    2008新版seo方程式SEO=∫Clock=∫C1+L2+K3+O4,之所以采用高等数学里积分的概念,是认为seo的时间原则是非常重要的,特别是对于反向链接的建设,尤为重要。

    增加反向链接是一个长期的积累过程,要循序渐进、一步一步来;如果在短时间内迅速增加了超乎寻常的反向链接数,很容易遭到搜索引擎的特别处理(沙盒效应),seo效果适得其反,自然无法获得好的搜索排名。

    2、数量原则

    在遵循时间原则的基础上,反向链接数量自然多多益善。正所谓“广种薄收”,“不积小流,无以成江海”,茫茫网海,一分耕耘一分收获。

    3、质量原则

      网站长久持续获得好的排名,反向链接的质量比数量更为重要。何谓高质量的反向链接?链接导入页面高Pr值和相关性决定了反向链接的质量。比如,你的网站是 seo相关的主题,那么来源于seo排名前10位的网站的导入链接一定是高质量的;来源于一篇seo相关文章的导入链接也一定是高质量的。但是,高质量的 反向链接是可遇不可求的,虽然一个高质量的反向链接抵得上几十个甚至上百个垃圾反向链接,但是在无法获得高质量反向链接的情况下,那就遵循数量原则。

    4、位置原则

    其实位置原则是质量原则的一个补充,因为容易忽视且重要性不亚于数量和质量原则,所以特别需要重视。所谓位置,指的是反向链接在导入链接页面的具体位置。 搜索引擎抓取页面的时候会给不同区域的内容给与不同的权重,一般上、左区域权重高、下(尾)权重低。因此,反向链接出现在导入页面不同的位置会有不同的投 票分数,建议:

    (1)如果有可能,那就让反向链接出现在导入页面的头部

    (2)如果有可能,那就让反向链接出现在导入页面的左侧

    (3)上述方法都不可能,那就让你的反向链接出现在内容区域的前面,相关性高的内容区域靠前的反向链接对搜索引擎排名极为有力!因此,写软文的特别注意,在文章开始的部分尽量加入你需要加入的“文字链”。

    (4)网页底部的友情链接是最没有价值的垃圾链接,但有总比没有强(数量原则)。
   
    以上介绍了反向链接的四大原则。链接的合理与丰富是第二位的要素,合理有效的内部链接与丰富的外部链接同等重要,而外部链接中高度相关性高Pr值页面尤为重要。

[工具]Haxe

mikel阅读(705)

Haxe和两三年前相比,现在已经很成熟了,很多人都说它的编译器比Flex的还要好,在性能优化、语法上有很多改进。不过并不冲突,可以取长补短。

Haxe的库现在是越来越多,各种引擎、框架、扩展。File Format是一个文件相关的库,用来解析或生成各种文件格式,比如swf、ABC(swf中的字节码)、Flv、Pbj(PixelBender的二进制格式)等等,在作者的TODO列表上,还有一串跟着。

我比较感兴趣的是pdf,编译了一个小小的例子试了下,在解析pdf时碰到了运行时错误。使用反编译器看了下代码,比较多比较乱,看的头昏,希望作者在后续可以完善这个库。

[JQuery]JQuery Maps

mikel阅读(702)

转载:http://www.cnblogs.com/RuiLei/archive/2009/11/25/1610163.html

Google Map应用在网站之上已经从单一的浏览性慢慢转化为服务概念(同时也大大增强用户体验度)

如下利用 Google Map Api —— 简单实现地图网站应用。(仅参考) 

实现目标:

1.在地图中进行地点标注

2.选择标注时,出现相关信息

3.点击页面上的测试按钮,显示相关的地点标注信息

Html Code:

<body > 
    <h1>Google Map</h1> 
    <div id="Googlemap" style="width: 70%; height: 480px; float: left; border: 1px solid black;"> 
    </div> 
    <input type="button" id="btnTest" title="test" value="显示第二店信息" />
 
</body>

 

前期准备:

  • 注册Google Api Key
  • 引用Google Api 脚本
 <script language="javascript" type="text/javascript" src=http://ditu.google.com/maps?file=api&v=2&key=XXX></script>

  

  • 在地图中进行地点标注

                如果要实现地点标注,首先要准备数据

                数据如下:

             var message = [ 
                         { "X": "31.223822", "Y": "121.336311", "Content": { "Title": "别克4s店", "Context": "北翟路1571号"} }, 
                         { "X": "31.175449", "Y": "121.395134", "Content": { "Title": "别克4s店", "Context": "虹梅路1601号"} }, 
                         { "X": "31.095711", "Y": "121.456276", "Content": { "Title": "别克4s店", "Context": "龙吴路"} }, 
                         { "X": "31.078356", "Y": "121.395607", "Content": { "Title": "别克4s店", "Context": "沪闵路"} }, 
                         { "X": "31.200939", "Y": "121.365707", "Content": { "Title": "别克4s店", "Context": "哈密路1231号"} } 
                                     ]; 

               然后调用

           addOverlay(overlay:GOverlay) 将叠加层添加到地图中,并触发 addoverlay 事件。

                  var point = new GLatLng(X, Y); 
                  var newMkr = GMaps.prototype.CreateMarker(point, i);
                  map.addOverlay(newMkr);

 

  • 选择标注时,出现相关信息

                 在标注点上显示相关信息,需要调用openInfoWindowHtml。

          openInfoWindowHtml(content:String, opts?:GInfoWindowOptions)
                通过标记图标打开地图信息窗口。信息窗口的内容为包含 HTML 文本的字符串。只适用于 GInfoWindowOptions.maxWidth 选项。

 

 

 

  • 点击页面上的测试按钮,显示相关的地点标注信息

                实现这点只需要定义一个Trigger即可

           GEvent.trigger(XX, "click");

 

代码解析:(看看注释即可)

        var message = [
                           { "X": "31.223822", "Y": "121.336311", "Content": { "Title": "别克4s店", "Context": "北翟路1571号"} },
                           { "X": "31.175449", "Y": "121.395134", "Content": { "Title": "别克4s店", "Context": "虹梅路1601号"} },
                           { "X": "31.095711", "Y": "121.456276", "Content": { "Title": "别克4s店", "Context": "龙吴路"} },
                           { "X": "31.078356", "Y": "121.395607", "Content": { "Title": "别克4s店", "Context": "沪闵路"} },
                           { "X": "31.200939", "Y": "121.365707", "Content": { "Title": "别克4s店", "Context": "哈密路1231号"} }
                      ];
 
        var GMaps = function() {
        };
 
        GMaps.prototype = {
 
            //定义标记容器
            makers: [],
 
 
            //定义鹰眼图标
            SetIcon: function(index) {
                var markerIcon = new GIcon();
                markerIcon.image = "../Images/" + index + ".png";
                return markerIcon;
            },
 
            //设置地图中心
            SetCenter: function(lats, lngs) {
                var maxLat = Math.max.apply(null, lats),
                maxLng = Math.max.apply(null, lngs),
                minLat = Math.min.apply(null, lats),
                minLng = Math.min.apply(null, lngs),
                lat = minLat + (maxLat - minLat) / 2,
                lng = minLng + (maxLng - minLng) / 2,
                //定义缩放率
                bounds = new GLatLngBounds(new GLatLng(minLat, minLng), new GLatLng(maxLat, maxLng));
                map.setCenter(new GLatLng(lat, lng), map.getBoundsZoomLevel(bounds));
            },
 
            //定义标记内容
            CreateMarker: function(latlng, index) {
                if (!latlng) return;
                var marker = new GMarker(latlng, { icon: GMaps.prototype.SetIcon(index) });
                marker.id = index;
 
                GEvent.addListener(marker, "click", function() {
                    var myHtml = new Array();
                    myHtml.push("<span id=\"Info\">");
                    myHtml.push("<h2>" + message[index].Content.Title + "</h2><br />");
                    myHtml.push(message[index].Content.Context + "<br />");
                    myHtml.push("</span>");
                    map.openInfoWindowHtml(latlng, myHtml.join(''));
                });
 
                return marker;
            },
 
            //设置触发标记内容显示
            TriggerMaker: function(maker) {
                GEvent.trigger(maker, "click");
            },
 
            //创建地图
            BuildMap: function(map) {
                //判断当前浏览器是否支持google 地图
                if (GBrowserIsCompatible()) {
                    //定义经纬度容器
                    var lats = [], lngs = [];
 
                    //从地图中删除所有叠加层
                    map.clearOverlays();
 
                    $.each(message, function(i) {
 
                        var point = new GLatLng(message[i].X, message[i].Y);
                        var newMkr = GMaps.prototype.CreateMarker(point, i);
                        if (newMkr) {
                            //存储当前Maker到Makers中,用于在地图之外进行选择
                            GMaps.prototype.makers.push(newMkr);
                            (function(map, newMkr) {
                                    //将叠加层添加到地图中
                                    map.addOverlay(newMkr);
 
                            })(map, newMkr);
                        }
                        //存储所有经纬度用于计算当前显示区域
                        lats.push(message[i].X);
                        lngs.push(message[i].Y);
                    });
 
                    //设置地图中心区域
                    GMaps.prototype.SetCenter(lats, lngs);
 
                    map.enableDoubleClickZoom();
                    map.enableScrollWheelZoom();
                    map.enableContinuousZoom();
 
                    map.addControl(new GLargeMapControl())
                    map.addControl(new GOverviewMapControl());
                    map.addControl(new GScaleControl());
                    map.addControl(new GMapTypeControl());
                }
                else {
                    alert("No Support Google Map");
                }
            }
        }

最后调用代码:

 

        var map = new GMap2(document.getElementById("Googlemap"));
 
        var mapView = new GMaps();
 
        mapView.BuildMap(map);
 
        $(function() {
 
            $("input[id=btnTest]").click(function() {
                mapView.TriggerMaker(mapView.makers[1]);
                if (document.documentElement.scrollTop > 250) document.documentElement.scrollTop = 170;
            });
        });

最终实现效果:

image

 

资源:

Google 地图 API 开发指南

 

待续  。。。。有关于Bing Maps的话题

[MVC]ASP.NET MVC实践系列9-filter原理与实践

mikel阅读(613)

转载:http://www.cnblogs.com/nuaalfm/archive/2009/11/24/1609752.html

filter实际上是一个特性(attribute),它提供了一种向controller 或 action中添加某些任务的方法,当controller 或 action被调用时,会触发filter中定义的相应方法。filter应该算AOP的一种实现方式,关于AOP的内容大家可以参考张逸的文章http://www.cnblogs.com/wayfarer/articles/241024.html,图文并茂对AOP讲解的十分清楚。所以我们就可以在某种程度上利用filter来分解横向和纵向的应用,比方说日志,权限,缓存,防盗链等等应用。

一、我们先来看看ASP.NET MVC 框架提供的几种默认filter类型:
1、Authorize:

准备工作:进入C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727文件夹,双击 aspnet_regSQL.exe选择好相应的数据库,创建membership,AuthorizeAttribute使用membership来进 行权限验证的,所以我们需要先在membership中准备一个用户lfm,一个角色Admin,我们使用studio的项目-》ASP.NET配置创建 即可。

  [Authorize(Roles="Admin")]
        
public ActionResult Index()
        {
            ViewData[
"Message"= "Welcome to ASP.NET MVC!";
            
return View();
        }

如果lfm不属于Admin角色时Index页是不能访问的

2、OutputCache:

 [OutputCache(Duration=60, VaryByParam="none")]
        
public ActionResult About()
        {
            
return View();
        }

然后我们修改About加入:

 <%=DateTime.Now.ToString() %>

我们会发现在一分钟内我们刷新About页面其输出并不改变。这个和webform中的页面缓存机制非常相似。

这里我们也可以统一的配置时间和条件


    <system.web>
      
<caching>
        
<outputCacheSettings>
          
<outputCacheProfiles>
            
<add name="MyProfile" duration=60” varyByParam=”none” />
          
</outputCacheProfiles>
        
</outputCacheSettings>
      
</caching>
    
</system.web>

Controler中输入

  [OutputCache(CacheProfile="MyProfile")]
        
public ActionResult About()
        {
            
return View();
        }

3、Exception


       [HandleError(ExceptionType = typeof(ArgumentException), View = "Error")]
        
public ActionResult GetProduct(string name)
        {
            
if (name == null)
            {
                
throw new ArgumentNullException("名字为空");
            }
            
return View();
        }

标明HandleError属性后的Action,当内部出现异常时会根据异常类型跳转到相应的View,这里需要注意的是上面的源码在开发期无法 看到效果,必须部署到iis上才能看到效果。实际上这个简单处理在项目中用处不大,一般我们都会写自己的异常处理方式,自定义异常处理我们一会再自定义 filter中讲解。

二、自定义filter实例:

我们先来看一下跟filter相关的类结构:

一般情况下我们自定义的filter都是继承FilterAttribute类然后再扩展相应的接口的,下面我们举几个例子:

1、自定义异常处理

自定义异常处理

使用

Controller

浏览器中输入:http://localhost:3983/Home/GetView

这样我们就可以根据自己的项目情况来处理异常了。

2、监控Action运行时间的Timer

TimerAttribute

使用

 [Timer]
        
public ActionResult TestTimer()
        {
            Thread.Sleep(
100);
            
return View();
        }

页面显示:

<%=ViewData["__Duration"]%>

三、filter相关接口方法的执行顺序:

根据上面的结构图我们知道跟filter相关的总共有四个接口,六个方法,这些方法如果在同一个类中实现时是有个优先级顺序的

IAuthorizationFilter>IActionFilter>IResultFilter>IExceptionFilter
接下来我们写个程序来验证这个顺序:

TestOrder属性类

使用

[TestOrder]
        
public ActionResult TestFilterOrder()
        {
           
// throw new Exception("lfm");
            return View();
        }

前端

<%throw new Exception("异常出现"); %>

这时候我们打开c:\test.txt得到的结果为:

OnAuthorization
OnActionExecuting
OnActionExecuted
OnResultExecuting
OnResultExecuted
OnException

四、参考

《Professional ASP.NET MVC 1.0》

http://www.cnblogs.com/leoo2sk/archive/2008/11/05/1326655.html

http://www.cnblogs.com/wayfarer/articles/241024.html

http://www.cnblogs.com/chsword/archive/2009/03/12/zd_mvc6.html

五、源码

 

我的ASP.NET MVC实践系列

ASP.NET MVC实践系列1-UrlRouting

ASP.NET MVC实践系列2-简单应用

ASP.NET MVC实践系列3-服务器端数据验证

ASP.NET MVC实践系列4-Ajax应用

ASP.NET MVC实践系列5-结合JQuery

ASP.NET MVC实践系列6-Grid实现(上)

ASP.NET MVC实践系列7-Grid实现(下-利用Contrib实现)

ASP.NET MVC实践系列8-对查询后分页处理的解决方案

其他:

在ASP.NET MVC中对表进行通用的增删改

[JQuery]thickbox使用指南

mikel阅读(553)

引用thickbox.css样式
引用thickbox.js脚本
动态创建thickbox方法:tb_show(caption, url, imageGroup);
参数说明:
caption:弹出窗口的标题
url:链接地址
imageGroup:图标
页面直接调用方法:
<a href="/info/index?width=240&hieght=300&id=23234" title="标题" class="thickbox">显示窗口</a>

[工具]让代码看起来更舒服(2):选择适合的字体

mikel阅读(622)

转载:http://www.cnblogs.com/xiaoshatian/archive/2009/11/23/1608432.html

上一篇文章我和大家分享了一些Visual Studio的配色方案,以及一个用来生成配色方案的网页版工具,现在我再来和大家分享一下Visual Studio的字体设置。

字体不仅是设计师手中重要的武器,对我们开发人员来说,字体的选择也有许多讲究,一个好的、适合展示代码的字体,应该具备以下要素:

  • 等宽的字符
  • 简洁、清晰并且规范的字符形状
  • 支持ASCII码为128以上的扩展字符集
  • 与字符同等宽度的空格
  • 易于分辨的小写字母l、大写字母I、数字1和符号|
  • 易于分辨的大写字母O和数字0
  • 易于分辨的前引号和后引号,最好能够前后对称
  • 易于分辨的其他标点符号,尤其是大括号、中括号、小括号和尖括号
  • 良好的中文支持和显示

下图展示了一个极端的反例,虽然很有个性,但并不适合用来显示代码。它的大写字母大的可怕,小写字母却小的可怜;字符不仅不清晰,而且不规范;小写字母l、大写字母I、数字1和符号| 难以分辨;大写字母O和数字0难以分辨;标点符号还凑合,只是下划线为什么是断开的?

image

当然,这个反例的确有些夸张,但其上文所列举的条件是比较苛刻的,我们在选择字体时没有必要非要完全满足所有条件,事实上这种字体也是凤毛麟角。下文所分享的一些字体也并没有完全满足所有条件,我们发现,只要满足了其中一些关键条件,用来显示代码就已经很不错了。

在Visual Studio中,更改编辑器的字体是件简单的事情,选择菜单【工具】【选项】,在弹出的“选项”对话框中依次选择“环境”和“字体和颜色”,然后在“显示其设置”中选择“文本编辑器”,最后在“字体”中选择字体就可以了,如下图所示:

image

在上图中,我们发现Visual Studio已经将等宽字体用粗体标识了出来,这样做是为了让我们更容易找到等宽的字体,并不表示等宽字体就一定适合显示代码,比如下图所示的“新宋体”就是一个反例:

image

在新宋体中,数字0之比大写字母O瘦那么一点点,小写字母l和数字1也十分相像,幸亏配色方案能够颜色将它们区别开来,否则实在难以分辨。这也从另一个角度说明了配色方案与字体是相辅相成的,搭配恰当时,会让代码更加清晰易辨。

下面就和大家分享一些在编程界声名烜赫的字体,截图所采用的配色方案为HumaneStudio,展示顺序为字体首字母升序。这些字体可能乍一看都一样,但仔细品味,还是能够发现不同的味道,希望大家都能找到适合自己的字体。

Andale Mono,演示字号为14,猛击这里下载

image

 

Anonymous Pro,演示字号为14,猛击这里下载

image

 

Bitstream Vera Sans Mono,演示字号为14,猛击这里下载

image

 

Consolas,演示字号为14,Windows或Visual Studio已内置:

image

 

Courier New,演示字号为14,Windows已内置:

image

 

DejaVu Sans Mono,演示字号为14,猛击这里下载

image

 

 

Envy Code R,演示字号为16,猛击这里下载

image

 

Inconsolata,演示字号为16,猛击这里下载

image

 

Monaco,演示字号为12,猛击这里下载

image

 

Monofur,演示字号为16,猛击这里下载

image

 

Progmata,演示字号为14,猛击这里下载

image

 

Share TechMono,演示字号为16,猛击这里下载

注:此字体似乎会将连在一起的fl显示为一个点,不建议使用,可惜可惜。

image

尾注:本文所分享的字体均支持ClearType。