posts - 24,comments - 228,trackbacks - 0
摘要: ASP.NET的SEO:基础知识ASP.NET的SEO:Global.asax和HttpModule中的RewritePath()方法——友好的URLASP.NET的SEO:正则表达式ASP.NET的SEO:服务器控件背后——SEO友好的Html和JavaScriptASP.NET的SEO:使用.ashx文件——排除重复内容A...阅读全文
posted @ 2010-02-19 20:29 自由飞 阅读(555) 评论(0) 编辑
磨蹭了好久,还是写一写吧,虽然我的英语水平目前也不是很好。

英语对于程序员来说,无论是从待遇,还是从技术发展的角度来看,都是一个必须得过的槛。我重新开始拾起英语,就是进入程序员这一行之后,那时,我已经大学毕业5年多了。

我在大学里过了6级,但和很多同龄人一样,靠的是阅读理解挣分,听力基本靠“蒙”,也就是所谓的哑巴英语,聋子英语。毕业后打算出国留学,要考雅思,所以曾经下狠“心”(但不是狠功夫,呵呵),猛补听力和口语,但效果都不好。感觉真正有所突破,还是这几年。

好了,直接所我的一些看法吧,更希望大家能给我也支支招,大家互相帮助,共同进步。:-)

第一、听说和读写哪个更重要。我记得我们大学的时候(1998-2002年),对传统英语教育骂声一片,“学了这么多年的英语,碰到一个老外,听不懂,说不出,失败呀!”。我也是其中振臂疾呼的愤青之一,呵呵。不过,现在看来,其实读写比听说用的地方多得多,书籍、文档、Email和IM,即使是telephone conference,也是有文本说明的。毕竟,英语,对我们而言,是一门“外语”。那我们还需不需要练听力和口语呢?我个人是这样认为的。这是一种理想,一种追求,是我长久以来的梦想:和一个来自遥远异国他乡的人,面对面的交流,悦耳的语音,像流畅的旋律……。当然,除此之外,如果听和说,也能促进我们的读和写;而且,让我们能谋得一个更好的职位,毕竟,口语好的求职者,还是要少很多。

第二、提高英语听力的方法。读是写的基础,听是说的基础。读写我就不浪费笔墨了,而听力的提高,是我们很多人长期的噩梦。我尝试过很多方法:传统的精听泛听、逆向法、千万别学英语和天涯漏屋的“悉得”法(姑且如是称之吧);试过好几种资料:大学教材,中级/高级听力,疯狂英语,电影和VOA……。就这些说说我的看法吧。

1、泛听的前提是精听。在这上面,我吃过大亏(可能也因人而异)。不知道你们看到过这种说法没有,“没事我就把耳机带着听,走路也听,吃饭也听,睡觉也听(睡前的效果还最好),开始什么也听不懂。但我还是接着听,就这样听呀听。结果有一天,忽然,我就发现,我居然发现,英语想流水一样飘过,我居然都能听懂啦!奇迹呀!”真的是奇迹,但这种奇迹从来没发生在我身上!?园子里有没有同学见证过这种奇迹?我从来没有。我支持逆向法,天涯漏屋也很明确的说了,“听不懂的声音就是噪音,就是无效输入,无效输入是没有任何作用的。”但我很奇怪,《千万别学英语》居然说,一个不懂任何日语的人,就收听日语电视节目,这样看呀看呀看呀看,看了几个月,就“自然而然”的懂日语了?而我当年,居然就信了!

泛听是最舒服的,舒服得完全可以做催眠特效药,是吧?多少个夜晚,我们在英语温柔的喃喃细雨中入眠?但就我的经验来看,他的作用是很微小的,尤其是当我们收听的是我们几乎无法理解的节目,如VOA Standard(甚至VOA Special,哪怕全神贯注,我们有多少人能一篇听懂100%?更何况是在走路的时候,吃饭的时候,睡觉的时候?)而且,这样泛听,还很有可能,让我们习惯于注意力涣散,抱着有一天“顿悟”的空想,而一旦希望破灭,莫名的烦躁沮丧……

对于泛听,我的理解:1、泛听意味着“大量”的听,要求我们听的量大;2、泛听训练我们从总体上把握材料的能力;所以,3、泛听绝对不是随随便便的“乱听”。所以,无论如何,泛听的结果必须是,最后,你是听懂了材料的,不要求100%,但80%,至少60%要吧?为了达到这种效果,很多老师前辈,都是说,泛听的难度不能太大,一定要大概能听懂的。

但我以前的水平,VOA Special都听不懂(一篇,那时只能收广播),还到哪里去找更简单的听力材料?但现在,让我泛听,随便听点VOA,不管Standard还是Specail,我就比较舒服了,能听懂,不会打瞌睡,而且还能学到点东西,一种表达法,听不懂的词,查查词典,也能有个结果,这就很爽了。但走到这一步,一定是精听的基础。逆向法绝对是精听的典型,强调“听写”,大家可以仔细看看。

这一条,概括起来说,就是,只有当你听力达到一定水平之后,泛听才能起作用。起步阶段,精听是绝对的基础。

2、首先听声音。这是《千万别学英语》给我最大的帮助(另外一个是使用英英词典)。如何有效的去精听?一句话过去了,我翻来覆去的听,就是听不清,听不懂,怎么办?这里,要区分“听不懂”和“听不清”,“听不懂”是可以理解的,但“听不清”呢?“听不懂”,指的是意思;“听不清”,指的是声音。这一句话的“声音”,你总该听“到”了的吧,那就把你听“到”的记下来。比如,“When it's very Dav mess”,“Dav mess”什么东西,谁也不知道,但这个声音你可以先记下来,然后和原文对比,你就会回发现问题,可能是出现了弱读、连读;或者是你没有辨音正确,他实际上是  Defence,那你就知道了,你区分不了f和v,m和n等……然后下意识的训练改正。
 
3、查词典和跟读。你听到的,不一定是正确的,比如,你认为你听到的,是sink,但实际上,是think。凡是碰到这种情况,不要轻易放过。这就算逆向法不看脚本查词典的好处。查词典,一定程度上,能逼着你努力的去听清楚,听正确。如果你这时候,看了一下脚本,你就很可能就放过了这个“辨音”点。随着你英语综合能力的提高,你可能就能根据上下文,自然的得出这里该是sink还是think的结论,但实际上,你还是不能区分th和s发音的区别,这就会导致你的发音出现问题。就像我是南方人,现在拼音打字都得开模糊音,分不清zh和z,这不影响我听懂普通话(尤其是在句子里),但会影响我的普通话发音。
你发不出某个音,一定是你听不“到”或者分辨不出来这个音。很多人发不准v和w,th和s,其实就算他们分辨不出这些音的区别(你们可以做个试验看看)。一个有助于解决这个问题的方法,就是跟读对比。录下你的发音,和原声对比,很多时候,是能听出差别来的。

4、不用强求英语思维。我们那时候,“英语思维”,是一个很时髦的说法。说不出,听不懂的原因,就是你不具有“英语思维”,你听到的每个单词,都要把它转换成汉语,然后再组合成句子,要花多长时间呀,等你完成了这些,人家都不知道说到哪里去了……所以“不要在头脑里翻译,直接用英语思维”。我觉得,听不懂的原因是找到了的;但解决的方法“不要在头脑里翻译,直接用英语思维”,这个解决问题的方法,值得商榷。
我很长一段时间都在这样尝试,但效果很差。第一,不翻译,怎么能理解?有些简单的,可能可以,Good Morning, Execuse me。但一旦复杂了,“The President's announcement was not from page news in most British newspapers, but one that did cover the decision call it a gamble and retreat(d)”,怎么办?怎样又才可以算“英语思维”?怎样才能达到“英语思维”?“不翻译”就可以了么?我觉得不是,这是一个“熟能生巧”的过程,在听的过程中,我们其实是无法“完全翻译”的,为了跟上说话者的节奏,我们自然的力图抓住说话者的意图,而忽略翻译的形式。如果你这做过翻译,你就会有这样的体会,这句话,我懂了他的意思;但让我把他翻译出来,还真得再仔细想想。但是我对这句话的理解,一定是汉语形式的,比如“总统”,“声明”,“报纸”等等,除非这里压根就没有,或者我根本就不知道“总统”这个汉语单词。这在我们的计算机专业里,会出现这种情况,比如,我们常说,team leader,谁都知道这个词的意思,但要把他翻译成汉语,可能大家都得想一想。
对于一个土生土长的中国人,完全的英语思维,没有及其特殊的环境(比如国外生活5年10年),其实是无法形成的。汉语已经烙入我们的灵魂,但这是我们的骄傲,汉语,美丽如斯!
相信我,你听不懂,只是你不够熟练。并不是翻译得不够熟练,而是理解得不够熟练。如果要做到熟练的翻译,在理解的基础上,还有很长很长的路要走,这条路,更陡峭,更险峻,更辉煌。

第三,平和的心态。

一上大学,我的英语学习目标就是,风度翩翩的和老外侃大山,没事就弄两部原声英语大片看看,像听新闻联播一样听VOA……然后,我干过很多傻事,直接买了一本《红与黑》的原著抱着啃,准备一学期啃完它;大一寒假我就买了《乱世佳人》的DVD,计划一个寒假把它给“搞定”;抱着单词书(听说还有被词典的,那个佩服呀)一天几百个的狂背,还要按遗忘曲线复习;……唯一没干过的就是跑到公交车上吼“疯狂英语”,可能那时候我已经感觉靠“疯狂”学英语不靠谱。

真正促使我反思的,是我老婆,她学日语的。绝对没有任何语言天赋:语文烂得一塌糊涂(可能我要去太高,呵呵),唱歌跑调跑到天上去了。更没有语言环境,日语绝对是上大学才开始认第一个字。没有任何特殊的学习方法和学习心得,完全是跟着课堂走,磁带是教材的配套,听广播是上到日语新闻这门课,老师要求听就听听,之后就没见她听过。一定要说一个什么方法,我说是,“胆小法”。大四了,一节课都还不敢翘,课前认真复习,课后按时完成作业(但仅限于能交差,因为他们老师要“抽查”)。说白了,整个大学四年,就像读了“轻松版”的四年高中。结果日语一级考试成绩,分数那个高,全西南地区第7名。我当时都傻眼了,现实版的郭靖呀。
但是她毕业后做口译,还是不行,被带了3、5个月,才慢慢上手的。
但即使现在,她完全胜任她的工作(日常的接待、洽谈、陪同翻译等),但看日语电影,听日语新闻,不看字幕,还是不行(至少不能一遍100%的听懂)

决心做程序员开始,我也同时重新拾起了我的英语。不过,这一次,没有什么宏伟的目标,没有什么眼花缭乱的学习方法,就早晚上下班(共2小时)听听VOA吧。
老老实实的从special开始,听了大概半年;然后开始standard,一直到现在。
先整段新闻的听几遍;然后按句子或意群,一个单词一个单词的抠;然后对照脚本,找出没有听正确的地方,最后还要再听几遍。这样下来,一段3分半钟左右的新闻,最开始1-2天能听完一篇,现在慢慢的一天能听3-4篇。
开始是很多单词看到就认识但就没听出来,这一般都是因为这个单词自己本来就不知道该怎么发音,或者自己的发音是错的;现在基本上听不懂的单词,自己也看不懂,就不认识,偶尔运气好,能根据发音查到单词,难的还是一些虚词,像区分and和in之类的,或者是几个虚词连在一起,as of it 之类的。
不给自己压力,必须每天听完多少多少,如果哪一天有点厌烦了,我会停下来,在地铁里傻傻的发愣,但我不会一连好几天都不听。其实地铁里也没什么事做,而且有点好奇,昨天下到手机里的新闻里究竟说的是什么呀?到后来,听英语成了一种习惯,不听就不自在。
我曾经试过每隔多久“复习”一下以前听过的东西,因为我发现,过一段时间再听以前的材料,当时没听懂的,哪怕看了脚本,现在还是很可能听不懂(呵呵,比较奇怪吧?)但后来,我觉得听已经知道了意思的新闻真的没什么意思,为了不破坏我愉快的情绪,算了,过去的就过去了……

如果只和昨天比,前天比,上一周比,我完全不能感觉到我的进步,甚至有时觉得会有退步(因为突然发现,这一段新闻,我居然完全不知所云;而昨天那篇新闻,我两篇就听懂了大意呀?!)。但回头看看,收获是沉甸甸的。

我仍然不能像听新闻联播一样听VOA,津津有味的欣赏没有字幕的英语大片。但我完全能够在一个纯英文的环境中,胜任我的工作,完成老外组织的纯英语的培训,参加各种全球客户的电话会议,中午吃饭时和老外你一言我一句的瞎掰,结结巴巴,但仍然谈笑风生。

我曾经复习4个月考过了司法资格考试,3个月考过软件设计师,但对于英语,我终于明白,一步一个脚印,持之以恒的坚持,是通向成功的唯一捷径。所以,在收获英语的同时,也收获了一份淡定从容。
posted @ 2011-07-31 00:50 自由飞 阅读(1992) 评论(32) 编辑

Orchard是一个基于.NET平台的开源CMS(Comment Management System)。园子里周金根同学有过介绍。

决定研究Orchard主要基于以下几个原因:

1. 技术很新。最近发布的版本居然都使用的是Asp.net MVC Razor!
2. 大量使用的开源技术,如NHibernate, Autofac等。
3. 架构很新颖(至少对于我来说),大量使用的IoC之类的让我彻底的云里雾里的了。
4. 活跃的社区支持,练习英文的好机会。

如果你和我一样,一起来看一看吧。再次呼吁,在博客园开一个Orchard栏目。支持的顶起呀!

官方网站:http://www.orchardproject.net/
社区支持:http://orchard.codeplex.com/discussions

posted @ 2011-01-23 10:59 自由飞 阅读(1899) 评论(6) 编辑

ASP.NET的SEO:目录 

 

黑帽(black hat)SEO主要是指采取“不怎么道德”(暂时就这么形容吧!)的方式进行搜索引擎优化。


1. 注入攻击,包括Sql注入和Html注入。我经常能看到对Sql注入防范的谈论,但对于Html注入,很多人并没有引起足够的重视。为了展示Html注入的效果,我们模仿了一个常见的留言本功能。
首先,在页面声明中添加两个属性设置EnableEventValidation="false" ValidateRequest="false" ,这很关键,读者可以试一下如果不这样设置会有什么效果。
<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" EnableEventValidation="false" ValidateRequest="false" %>

然后,前台页面和后台代码段分别如下:
代码
        <asp:TextBox ID="txtInput" runat="server" Height="95px" Width="405px" TextMode="MultiLine"></asp:TextBox>
        
<asp:Button ID="btnSubmit" runat="server" Text="Simple Submit"
            onclick="btnSubmit_Click" />
        
<asp:Label ID="lblShow" runat="server"></asp:Label>

    protected void btnSubmit_Click(object sender, EventArgs e)
    {
        
this.lblShow.Text = this.txtInput.Text;
    }



程序很简单,将用户输入的内容再显示出来而已。运行代码,然后输入我们的恶意代码,提交。
<p>Sanitizing <img src=""INVALID-IMAGE" onerror='location.href="http://too.much.spam/"'>!</p>

我们会发现页面自动跳转到http://too.much.spam/页面!这就是所谓的“Html注入”。当page页面render到客户端后,浏览器会按一个普通的html页面进行解析;当解析到上面的js代码时……

为了避免这种入侵,在asp.net中,我们最简单的处理方式就是对输入的内容进行“Html编码”。将后台代码改为:
    protected void btnSubmit_Click(object sender, EventArgs e)
    {
        
this.lblShow.Text = this.Server.HtmlEncode(this.txtInput.Text);
    }

现在我们再运行代码,发现源代码被原样输出显示在页面,并没有运行。为什么呢?查看输出页面的源代码:
   <span id="lblShow">&lt;p&gt;Sanitizing &lt;img src=&quot;&quot;INVALID-IMAGE&quot; onerror='location.href=&quot;http://too.much.spam/&quot;'&gt;!&lt;/p&gt;</span>
整理后,我们发现如下的映射转换:
<  --  &lt;  (less than)
>  --  &gt;  (greater than)
"  --  &quot;   (quota)
所以js无法执行,但在页面显示时,我们确能看到“原汁原味”的js内容。

但问题并没有结束,现实世界中,输入的内容除了恶意代码以外,还可能有如下的内容:
<span style=" color:blue">黑帽</span>(black hat)SEO主要是指采取<span style=" color:blue">“不怎么道德”</span>(暂时就这么形容吧!)的方式进行搜索引擎优化。

我们希望显示蓝色的文字,但经过编码后,显然无法达到我们的效果。为此,我们还需要进行更精确的过滤。这也是为什么之前我们要设置EnableEventValidation="false" ValidateRequest="false"的现实原因。
其实我最先想到的方案是:首先对整个内容进行编码,然后把我们允许使用的html标签再替换回来。这样是相当保险的,但是在具体的操作中,遇到了很多问题,这个郁闷啊~~~(如果有谁有这种方式的实现代码,千万要拿出来大家分享一下呀)。
我先介绍另一种方案:
首先要取出标签,如,<span style=" color:blue">、</span>和<script  >,我们的替换范围仅局限于标签 < > 之间的内容。
然后获取所有的标签名称、属性的名称和值,如果有禁止出现的内容,就替换掉。可能的恶意代码形式如下所示:
标签的名称: <script  </script               
标签里的属性:<span onclick
属性的值:<img onerror="javascript:"
最后,我们对所有的“恶意单词”进行替换:
代码


using System;
using System.Text.RegularExpressions;

/// <summary>
/// Sanitize contains functionality to remove unaccepted tags or attributes
/// </summary>
public static class Sanitize
{
  
// list of accepted/harmeless tags (in lower case)
  private static string[] allowedTags =     
    { "p""h1""b""i""a""ul""li""pre""hr""blockquote""img" };

  
// list of attributes that need to be sanitized
  private static string badAttributes =
    
"onerror|onmousemove|onmouseout|onmouseover|" +
     
"onkeypress|onkeydown|onkeyup|javascript:";

  
// sanitizes the HTML code in $inputHTML
  public static string FixTags(string inputHtml)
  {
    
// define the match evaluator
    
// MatchEvaluator 是一个委托,它调用fixTag方法
    MatchEvaluator fixThisLink = new MatchEvaluator(Sanitize.fixTag);

    
// process each tags in the input string
    string fixedHtml = Regex.Replace(inputHtml,         //需要替换的字符串
                                     "(<.*?>)",         //正则表达式:注意“?”的使用   --贪婪模式
                                     fixThisLink,       //委托“实例”做参数
                                     RegexOptions.IgnoreCase);
    
//整句代码的意思就是:将输入字符串inputHtml中能匹配上"(<.*?>)"的部分(也就是被<  >包裹的标签)用fixThisLink方法进行处理

    
// return the "fixed" input string
    return fixedHtml;
  }

  
// remove tag if is not in the list of allowed tags
  private static string fixTag(Match tagMatch)
  {
    
string tag = tagMatch.Value;

    
// extrag the tag name, such as "a" or "h1"
    Match m = Regex.Match(tag,
                          
@"</?(?<tagName>[^\s/]*)[>\s/]",       
                          RegexOptions.IgnoreCase);
    
string tagName = m.Groups["tagName"].Value.ToLower();

    
// if the tag isn't in the list of allowed tags, it should be removed
    if (Array.IndexOf(allowedTags, tagName) < 0)
    {
      
return "";
    }

    
// remove bad attributes from the tag
    string fixedTag = Regex.Replace(tag,
                        
"(" + Sanitize.badAttributes + @")(\s*)(?==)",    // 注意"?=="的意思  --正向预查
                        "SANITIZED", RegexOptions.IgnoreCase);

    
// return the altered tag
    return fixedTag;
  }
}

注意代码中两处正则表达式的高级用法,贪婪模式和正向预查,详细可参考贪婪模式正向预查
这里我们就可以看到正则表达式说起到的强大作用——操作字符串的无上利器啊!


2. 除了注入攻击,另一种必须使用的技术是nofollow。因为Google的链接价值算法,我们都希望能有高价值的链接能指向我们的网站,以提高我们网站的等级。一种简单的方式就是到其他网站(如新浪)申请一个博客,然后在博客里添加一条链接,指向自己的网站即可。但如果我们自己是新浪,我们当然不愿意有其他人这样做(毕竟我们不知道其他人链接指向的网站究竟是好是坏,如果是一个垃圾网站,会牵连到我们自己的)。但是呢,我们也不愿意完全禁止掉链接的使用(比如简单的对链接进行编码,让链接失去作用),因为毕竟很多链接或许只是内部链接,而且一个能直接点击的链接能带来更好的用户体验。
为了解决这个问题,Google给出了一个方法,在链接中加上关键字nofollow,如下所示:
<a rel="nofollow" href="http://too.much.spam">cool link</a>
这样,链接能直接点击,但不会带来链接价值——即Google不会认为你认可或推荐了该链接指向的网站。看看博客园有没有这样做,……,呵呵,好像没有,很大度哟。不过据说Google也会逐步降低链接价值的作用,谣言了,随他去吧……
就直接上代码了:

代码
using System;
using System.Text.RegularExpressions;

/// <summary>
/// NoFollow contains the functionality to add rel=nofollow to unstusted links
/// </summary>
public static class NoFollow
{
  
// the white list of domains (in lower case)
  private static string[] whitelist =     
     { "seoasp""www.seoegghead.com""www.cristiandarie.ro" };

  
// finds all the links in the input string and processes them using fixLink
  public static string FixLinks(string input)
  {
    
// define the match evaluator
    MatchEvaluator fixThisLink = new MatchEvaluator(NoFollow.fixLink);

    
// fix the links in the input string
    string fixedInput = Regex.Replace(input,
                                      
"(<a.*?>)",
                                      fixThisLink,
                                      RegexOptions.IgnoreCase);

    
// return the "fixed" input string
    return fixedInput;
  }

  
// receives a Regex match that contains a link such as
  
// <a href="http://too.much.spam/"> and adds ref=nofollow if needed
  private static string fixLink(Match linkMatch)
  {
    
// retrieve the link from the received Match
    string singleLink = linkMatch.Value;

    
// if the link already has rel=nofollow, return it back as it is
    if (Regex.IsMatch(singleLink,
                      
@"rel\s*?=\s*?['""]?.*?nofollow.*?['""]?",
                      RegexOptions.IgnoreCase))
    {
      
return singleLink;
    }

    
// use a named group to extract the URL from the link
    Match m = Regex.Match(singleLink,
                          
@"href\s*?=\s*?['""]?(?<url>[^'""]*)['""]?",
                          RegexOptions.IgnoreCase);
    
string url = m.Groups["url"].Value;

    
// if URL doesn't contain http://, assume it's a local link
    if (!url.Contains("http://"))
    {
      
return singleLink;
    }

    
// extract the host name (such as www.cristiandarie.ro) from the URL
    Uri uri = new Uri(url);
    
string host = uri.Host.ToLower();

    
// if the host is in the whitelist, don't alter it
    if (Array.IndexOf(whitelist, host) >= 0)
    {
      
return singleLink;
    }

    
// if the URL already has a rel attribute, change its value to nofollow
    string newLink = Regex.Replace(singleLink,
             
@"(?<a>rel\s*=\s*(?<b>['""]?))((?<c>[^'""\s]*|[^'""]*))(?<d>['""]?)?",
             
"${a}nofollow${d}",
             RegexOptions.IgnoreCase);

    
// if the string had a rel attribute that we changed, return the new link
    if (newLink != singleLink)
    {
      
return newLink;
    }

    
// if we reached this point, we need to add rel=nofollow to our link
    newLink = Regex.Replace(singleLink, "<a"@"<a rel=""nofollow""",
                            RegexOptions.IgnoreCase);
    
return newLink;
  }
}
posted @ 2010-03-12 21:30 自由飞 阅读(1322) 评论(3) 编辑
今天突然发现Reset按钮在回发之后就不起作用了,清不掉TextBox里的值。
    <input type="reset" value="reset" />

网上搜了一下,只有问题,没有答案。csdn上一个老帖子里说和ViewState之类的有关,把我还搞得晕乎乎的,想想reset按钮怎么也就是一个客户端的控件,和服务器端根本不搭界,怎么可能呢?ViewState怎么也得到了服务器端才开始解析呀。

结构后来仔细一对比TextBox生成的Html代码:
    <input name="txt" type="text" id="txt" />
    <input name="txt" type="text" value="dfsa" id="txt" />

原来页面postback,再render之后,value值都被写死了,还怎么reset?
reset只能清除掉用户输入的内容啊!~~~

posted @ 2010-03-02 18:49 自由飞 阅读(291) 评论(0) 编辑
本系列目录

网站地图的作用是让搜索引擎尽快的,更多的收录网站的各个网页。
    
这里我们首先要明白一个基本的原理,搜索引擎的爬行方式。整个互联网就像一张纵横交错的“网”:网的各个节点就是各个网页,而各个网页之间通过url相互连接。蜘蛛可以从一个网页出发,通过该网页上的url,爬到另一个网页;再通过另一个网页上的url,再爬到更多的网页……,以此类推。但如果是一个新发布的网站,可能就没有其他url指向它,那么它就永远不会被“爬到”(收录)。为了解决这个问题,新站可以自己主动向搜索引擎提交url,申请蜘蛛前来抓取(Google申请网址:),但申请时一般只会提交一个主页的url。

为了让所有的url(尤其是动态生成的)都能被蜘蛛快捷便利的检索到,我们就需要提供一个全面完整、架构清晰和更新及时的网站地图。(网站地图的更多信息)。

和处理重复内容的robots.txt文件,我们通过.ashx文件来生成一个基于sitemaps.org的xml格式的网站地图。网站地图生成之后,我们就可以向Google等搜索引擎提交。大量的文章证实,提交网站地图将极大的提高网站的收录速度和深度。其他几乎所有的SEO方法,都有可能效果难以证实、失效甚至带来副作用,但提交网站地图除外!


Linq to XML为我们带来了近乎完美的操作体验。

WebSite
<%@ WebHandler Language="C#" Class="website" %>

using System;
using System.Web;
using System.Xml;
using System.Xml.Linq;
using System.Linq;

public class website : IHttpHandler {
    
    
public void ProcessRequest (HttpContext context) {

        context.Response.ContentType = "text/xml";

        
//文件的声明信息,第第三个参数standalone的值yes 表示这个 XML 文档是自包含的(self-contained)而不依赖于外部所定义的一个 DTD. 
        XDeclaration declaration = new XDeclaration("1.0""UTF-8""yes");
        context.Response.Write(declaration);
        
        
//XML文件的命名空间
        XNamespace ns = "http://www.google.com/schemas/sitemap/0.84";
        XElement siteMap = new XElement(ns + "urlset");

        
string fixedUrl = "http://www.freeflying.com/article";
        
string wholeUrl = string.Empty;
        
        
//循环取出数据,转换成XML节点
        foreach (var item in Articles.GetArticles())
        {
            XElement url = new XElement("url");

            wholeUrl = string.Format("{0}?id={1}&catelog={2}",fixedUrl,item.ID,item.Catelog); 
            XElement loc = new XElement("loc", wholeUrl);
            XElement lastmod = new XElement("lastmod", item.LastMod.AddDays(-23).ToShortDateString());
            XElement changefreq = new XElement("changefreq", item.Frequency);
            XElement priority = new XElement("priority", item.Weight);

            url.Add(loc, lastmod, changefreq, priority);

            siteMap.Add(url);
        }

        
        
        
//最后输出整个xml文件
        context.Response.Write(siteMap);
    }
 
    
public bool IsReusable {
        
get {
            
return false;
        }
    }

}

 

同样还将使用到xml技术的还有RSS

RSS
<%@ WebHandler Language="C#" Class="rss" %>

using System;
using System.Web;
using System.Xml;
using System.Xml.Linq;


public class rss : IHttpHandler {
    
    
public void ProcessRequest (HttpContext context) {
        context.Response.ContentType = "text/xml";

        context.Response.Write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");

        XElement rssFeed = new XElement("rss"new XAttribute("version","2.0"));

        
string fixedUrl = "http://www.freeflying.com/article";
        
string wholeUrl = string.Empty;

        XElement channel = new XElement("channel",
            
new XElement("title""freeflying"),
            
new XElement("link", fixedUrl),
            
new XElement("description","the website for dream flying freely"),
            
new XElement("pubDate",DateTime.Now.ToString())
            );
        
        
        
foreach (var article in Articles.GetArticles())
        {
            XElement item = new XElement("item");

            XElement title = new XElement("title", article.Title);

            wholeUrl = string.Format("{0}?id={1}&catelog={2}", fixedUrl, article.ID, article.Catelog);
            XElement link = new XElement("link", wholeUrl);

            XElement description = new XElement("description", article.Description);

            XElement pubDate = new XElement("pubDate", article.LastMod.ToString());

            item.Add(title,link,description,pubDate);

            channel.Add(item);
        }

        rssFeed.Add(channel);

        context.Response.Write(rssFeed);

    }
 
    
public bool IsReusable {
        
get {
            
return false;
        }
    }
    

}

   

模拟数据
using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Web.UI.MobileControls;
using System.Collections.Generic;

/// <summary>
/// Summary description for Articles
/// </summary>
public class Articles
{
    
public Articles()
    {
        
//
        
// TODO: Add constructor logic here
        
//
    }

    
public static List<Article> GetArticles()
    {
        
return new List<Article>(){
            
new Article(234"blog", DateTime.Now.AddDays(-23), Freq.none, 0.8"asp.net seo""articles about SEO in asp.net"),
            
new Article(267"blog", DateTime.Now.AddDays(-245), Freq.daily, 0.6"ado.net pro","about the dataset usage"),
            
new Article(653"news", DateTime.Now.AddDays(-45), Freq.daily, 1,"CLR via C#","notebook about this book")
        };
    }


}

public class Article
{
    
public int ID;
    
public string Catelog;
    
public DateTime LastMod;
    
public double Weight;
    
public Freq Frequency;
    
public string Title;
    
public string Description;

    
public Article(int id, string catelog, DateTime lastMod, Freq frequency, double weight, string title, string description)
    {
        ID = id;
        Catelog = catelog;
        LastMod = lastMod;
        Weight = weight;
        Frequency = frequency;
        Title = title;
        Description = description;
    }
}

public enum Freq
{
    none = 1,
    daily = 2,
    weekly = 3,
}


posted @ 2010-02-26 21:15 自由飞 阅读(1648) 评论(2) 编辑
摘要: 本系列目录我们经常说“404错误”,你知道他指的是什么意思么?404其实是Http报头所包含的一个“状态码”,表明该Http请求失败。那么除此之外,还有哪些常用的状态码呢?这些状态码和SEO又有什么关系呢?每次当用户代理(可以理解为就是IE和Firefox)向Web站点请求一个URL地址,服务器都会给予回复,回复内容包括两部分:HTTP报头,和被请求...阅读全文
posted @ 2010-02-24 00:56 自由飞 阅读(1809) 评论(3) 编辑
摘要: 本系列目录 不同的链接指向的页面如果具有大量相同的内容,这种现象就会被称为“重复内容”,如果一个网站的重复内容很多,搜索引擎就会认为这个网站的价值不高。所以我们应尽量避免各种重复内容。动态网站的重复内容常常是由URL参数引起的,而URL重写会恶化这一现象(比较耐人寻味哟,呵呵)。因为如果使用的是原始的URL参数的话,搜索引擎可能会进行适当的判断,而得知重复内容是由URL参数...阅读全文
posted @ 2010-02-21 22:22 自由飞 阅读(2053) 评论(6) 编辑
摘要: ASP.NET的SEO:基础知识ASP.NET的SEO:Global.asax和HttpModule中的RewritePath()方法——友好的URLASP.NET的SEO:正则表达式ASP.NET的SEO:服务器控件背后——SEO友好的Html和JavaScriptASP.NET的SEO:使用.ashx文件——排除重复内容A...阅读全文
posted @ 2010-02-19 20:29 自由飞 阅读(555) 评论(0) 编辑
摘要: 本系列目录 假设你需要从一个页面转向其他页面,下面有很多种方式,你是如何选择的呢?你能清晰的说明理由么?[代码] 如果你还有些迷茫,我建议你查看他们生成html之后的源代码。Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--><aid="HyperL...阅读全文
posted @ 2010-02-19 19:56 自由飞 阅读(1777) 评论(7) 编辑
摘要: 本系列目录 因为在网上搜到了很多这方面的文章,而且UrlRewrite中SEO中的重要性也在逐步下降,所以这一节我就写得简单一些。以下是几个重点:1.UrlRewrite,顾名思义,只是针对URL进行的重写操作,不要认为www.freeflying.com/Jack/articles-2467.html就真的对应着一个html文件:articles-2467.html;实际上,该链接真正对应的是w...阅读全文
posted @ 2010-02-14 14:42 自由飞 阅读(551) 评论(0) 编辑