SEO_ASP.net SEO优化(包含URL地址重写\viewState移动和压缩至服务器\SEO信息XML生成_根据URL地址重写文件)\web网站内容压缩 源码公开.本人授权可使用于商业项目。

1 篇文章 0 订阅

说明:我的环境是vs2010

我们像程序调试的模式一步一步的来看。

1、首先我们来看我的页面

       
  public partial class index : Optimization_WebPage.BasePage
    {
	 protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {

            }
            base.SEO_PageName = "index";
        }
    }


2、这里我们在看母版页

    /// <summary>
    /// 页面基类:这里做了对页面的viewstate优化和Seo操作
    /// </summary>
    public class BasePage : Page
    {
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            this.SetOptimization();
            this.SetSEOParameters(Seo);
        }

        protected override void OnUnload(EventArgs e)
        {
            dicCacheKey = null;
            seo = null;
            sEO_PageName = null;
            base.OnUnload(e);
        }

        #region viewstate压缩优化

        /// <summary>
        /// 加载优化后的viewState
        /// 作者:shawn
        /// TIME :2011.12.19
        /// </summary>
        /// <returns></returns>
        protected override object LoadPageStateFromPersistenceMedium()
        {
            var viewStateID = (string)((Pair)base.LoadPageStateFromPersistenceMedium()).Second;
            var stateStr = (string)Cache[viewStateID];
            if (stateStr == null)
            {
                var fn = Path.Combine(this.Request.PhysicalApplicationPath, @"App_Data/ViewState/" + viewStateID);
                stateStr = File.ReadAllText(fn);
            }
            return new ObjectStateFormatter().Deserialize(stateStr);
        }


        /// <summary>
        /// 将viewState优化并进行保存操作
        /// 作者: shawn
        /// Time : 2011.12.19
        /// </summary>
        /// <param name="state"></param>
        protected override void SavePageStateToPersistenceMedium(object state)
        {
            var value = new ObjectStateFormatter().Serialize(state);
            var viewStateID = (DateTime.Now.Ticks + (long)this.GetHashCode()).ToString(); //产生离散的id号码
            var fn = Path.Combine(this.Request.PhysicalApplicationPath, @"App_Data/ViewState/" + viewStateID);
            File.WriteAllText(fn, value);
            Cache.Insert(viewStateID, value);
            base.SavePageStateToPersistenceMedium(viewStateID);
        }

        #endregion

        #region seo相关操作
        /// <summary>
        /// 页面相关SEO信息设定
        /// </summary>
        /// <param name="title">页面标题.不能为空</param>
        /// <param name="seo">seo信息类.keyweords和descrption属性不能为空。否则程序异常</param>
        public virtual void SetSEOParameters(SEOParameters seo)
        {
		//其实下面的各个属性值可以再加上程序动态生成的一些值。例如:*****水果 + seo专员固定写的的seo信息。
		//例title.text = title.text + seo.SEO_title。而且还可以增加配置文件来设置规则。好比规则是好比固定的内容在前面。动态的在后面等等

            if (Seo != null)
            {
                HtmlMeta
                    keywd = new HtmlMeta(),
                    desprtion = new HtmlMeta(),
                    author = new HtmlMeta(), // author
                    copyright = new HtmlMeta(), // copyright
                    date = new HtmlMeta(), // date
                    robots = new HtmlMeta(),// robots
                    equiv = new HtmlMeta(),
                    language = new HtmlMeta(),
                    client_equiv = new HtmlMeta();
                HtmlTitle title = new HtmlTitle();
                //标题
                title.Text = seo.SEO_title;
                //关键词
                keywd.HttpEquiv = "keywords";
                keywd.Content = seo.SEO_keyWords;

                //描述信息
                desprtion.HttpEquiv = "description";
                desprtion.Content = seo.SEO_desprtion;

                //编码
                equiv.HttpEquiv = "Content-Type";
                equiv.Content = seo.SEO_ecoding;

                //渲染器选择
                client_equiv.HttpEquiv = "X-UA-Compatible";
                client_equiv.Content = seo.SEO_clientContent;

                //语言
                language.HttpEquiv = "Content-Language";
                language.Content = seo.SEO_languagestr;

                //作者
                author.Name = "Author";
                author.Content = seo.SEO_authorContent;

                //版权所有
                copyright.Name = "copyright";
                copyright.Content = seo.SEO_copyrightContent;

                //日期
                date.Name = "date";
                date.Content = DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString();

                //robots针对搜索引擎
                robots.Name = "robots";
                robots.Content = seo.SEO_urlRoobts;
                //将创建的各个SEO标签添加到header

                this.Header.Controls.AddAt(0, title);
                this.Header.Controls.AddAt(1, keywd);
                this.Header.Controls.AddAt(2, desprtion);
                this.Header.Controls.AddAt(3, equiv);
                this.Header.Controls.AddAt(4, client_equiv);
                this.Header.Controls.AddAt(5, language);
                this.Header.Controls.AddAt(6, author);
                this.Header.Controls.AddAt(7, copyright);
                this.Header.Controls.AddAt(8, date);
                this.Header.Controls.AddAt(9, robots);

            }
        }

        Dictionary<string, SEOParameters> dicCacheKey = null;

        /// <summary>
        /// 供外部调用获取已加载到缓存中的seo.xml文件.
        /// </summary>
        Dictionary<string, SEOParameters> DicCacheKey
        {
            get
            {
                if (dicCacheKey == null)
                {
                    dicCacheKey = Cache["seoCache_Dic"] as Dictionary<string, SEOParameters>;
                }
                return dicCacheKey;
            }
            set { dicCacheKey = value; }
        }

        SEOParameters seo = null;
        /// <summary>
        /// seo优化信息实体该值.具体页面指定.如现优化页面为index.那么使用实例为:
        /// base.Seo = base.DicCacheKey["index"] as SEOParameters;
        /// </summary>
        SEOParameters Seo
        {
            get
            {
                if (seo == null)
                {
                    if (SEO_PageName != null)
                    {
                        if (DicCacheKey != null)
                        {
                            if (DicCacheKey[SEO_PageName] != null)
                            {
                                seo = DicCacheKey[SEO_PageName] as SEOParameters;
                            }
                        }
                    }
                }
                return seo;
            }
            set { seo = value; }
        }

        string sEO_PageName;
        /// <summary>
        /// 对应VirtualPath.xml需要做优化的页面名字.实例:index.aspx或index.html写为index
        /// </summary>
        public string SEO_PageName
        {
            get { return sEO_PageName; }
            set { sEO_PageName = value; }
        }

        #endregion 

        #region  .NET渲染代码以及空白字符优化处理
        /// <summary>
        /// 加载优化
        /// </summary>
        void SetOptimization() 
        {
            if (!NoOptimizationNuLLStr)
            {
                HttpContext.Current.Cache.Insert("OptimizationNuLLStr", true); //其实这里还可以进行封装。慢慢去扩展、吧
            }
            else
            {
                HttpContext.Current.Cache.Insert("OptimizationNuLLStr", false);
 //其实这里还可以进行封装。慢慢去扩展、吧
} if (!NoMovieNetCode) { HttpContext.Current.Cache.Insert("MovieNetCode", true);
 //其实这里还可以进行封装。慢慢去扩展、吧
} else { HttpContext.Current.Cache.Insert("MovieNetCode", false);
 //其实这里还可以进行封装。慢慢去扩展、吧
} } bool noOptimizationNuLLStr; /// <summary> /// 指示当前页面是否进行空字符的优化处理.如果不进行相关处理由继承页面将该值设为true /// </summary> public bool NoOptimizationNuLLStr { get { return noOptimizationNuLLStr;} set { noOptimizationNuLLStr = value; } } bool noMovieNetCode; /// <summary> /// 指示当前页面是否进行.NET渲染出的代码移动处理.如果不进行相关处理由继承页面将该值设为true /// </summary> public bool NoMovieNetCode { get { return noMovieNetCode; } set { noMovieNetCode = value; } } #endregion }


很清楚这个页面主要做的事情1、将需要调用的SEO信息的页面名称放入键值对2、加载对应Seo的相关信息。3、viewState压缩保存至服务器端

为什么这么做。很简单。因为程序不知道是哪个页面调用放在缓存中的seo的信息。其实这个basepgae只是取值把值赋予seo的属性在返回给继承它的页面,所以,效率嘛。还是很快的。而且用的是缓存,不存在数据读取等一系列操作。那么问题出来了。我们是什么时候把seo的信息缓存起来的呢?保存在哪呢?seo专员需要修改的时候怎么办呢?

ok,我们接下来就解决这个问题。


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Caching;
using Optimization_WebPage;
using System.Xml;
using System.IO;

namespace Optimization_WebPage.ViewState
{
    public class SEOSetXMLCache:IHttpModule
    {
        public void Dispose()
        {
            
        }


        public void Init(HttpApplication context)
        {
            context.BeginRequest += new EventHandler(context_UpdateRequestCache);
        }

        /// <summary>
        /// 注册事件.进行事件执行.将 URL地址重写xml数据读入SEOxml。并将SEO xml文档中的数据缓存
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void context_UpdateRequestCache(object sender, EventArgs e)
        {
            System.Web.HttpApplication application = (System.Web.HttpApplication)sender;
            //将 URL地址重写xml数据读入SEOxml
            this.SetSeoXmlByVirtualPath(application);
            //并将SEO xml文档中的数据缓存
            if (application.Context.Cache["seoCache_Dic"] == null)
            {
                this.GetSeoCache(application.Context);
            }
        }

        #region 将SEO xml文档中的数据缓存
        /// <summary>
        /// 对seo相关数据的 xml文档的数据加载到cache缓存
        /// </summary>
        void GetSeoCache(HttpContext Context)
        {
            XmlDocument xmlDoc = new XmlDocument();
            string tmpPath = HttpContext.Current.Server.MapPath("~/Seo.xml");
            if(File.Exists(tmpPath))
            {
                xmlDoc.Load(tmpPath);
                XmlNodeList xmlNodelist = xmlDoc.SelectSingleNode("Root").ChildNodes;
                Dictionary<string, SEOParameters> dic_seo = new Dictionary<string, SEOParameters>();
                for (int i = 0; i < xmlNodelist.Count; i++)
                {
                    if (HttpContext.Current.Cache[xmlNodelist.Item(i).Name] == null)
                    {
                        this.SetSEOCache(dic_seo, Context, i, xmlDoc, tmpPath);
                    }
                }
                Context.Cache.Insert("seoCache_Dic", dic_seo, new CacheDependency(tmpPath));
            }
        }

        void SetSEOCache(Dictionary<string, SEOParameters> dic_seo, HttpContext Context, int i, XmlDocument xmlDoc, string tmpPath)
        {
            XmlNodeList xmlNodelist = xmlDoc.SelectSingleNode("Root").ChildNodes;
            dic_seo.Add(xmlNodelist.Item(i).Name, LoadXmlGetSeoParameter(xmlNodelist.Item(i).Name, xmlDoc));
            //Context.Cache.Insert(xmlNodelist.Item(i).Name, LoadXmlGetSeoParameter(xmlNodelist.Item(i).Name, xmlDoc), new CacheDependency(tmpPath));
        }

        /// <summary>
        /// 通过二级节点名获取二级节点下得节点
        /// </summary>
        /// <param name="NodesName"></param>
        /// <returns></returns>
        SEOParameters LoadXmlGetSeoParameter(string NodesName, XmlDocument xmlDoc)
        {
            SEOParameters seo = new SEOParameters();
            XmlNodeList xmlNodeList = xmlDoc.SelectSingleNode("Root").SelectSingleNode(NodesName).ChildNodes;
            foreach (XmlNode xmlNode in xmlNodeList)
            {
                XmlElement mypara = (XmlElement)xmlNode;
                switch (mypara.Name)
                {
                    case "title":
                        seo.SEO_title = mypara.InnerText;
                        break;
                    case "discription":
                        seo.SEO_desprtion = mypara.InnerText;
                        break;
                    case "keywords":
                        seo.SEO_keyWords = mypara.InnerText;
                        break;
                    default:
                        seo.SEO_title = "";
                        seo.SEO_desprtion = "";
                        seo.SEO_keyWords = "";
                        break;
                }
            }
            return seo;
        }

        #endregion

        #region 将 URL地址重写xml数据读入SEOxml
        void SetSeoXmlByVirtualPath(HttpApplication app)
        {
            if (app.Context.Cache["IsSetSeoXmlByVirtualPath"] != null)
            {
                string Isload = app.Context.Cache["IsSetSeoXmlByVirtualPath"].ToString();
                if (Isload == "Yes")
                {
                    string tmpPathSeo = HttpContext.Current.Server.MapPath("~/Seo.xml");
                    XmlDocument xmlSeo = null;
                    if (!File.Exists(tmpPathSeo))
                    {
                        this.AddNodeByXML(xmlSeo, tmpPathSeo);
                    }
                    else
                    {
                        File.Delete(tmpPathSeo);
                        this.AddNodeByXML(xmlSeo, tmpPathSeo);
                    }
                }
            }
        }

        /// <summary>
        /// 向SEO xml文档中插入节点
        /// </summary>
        /// <param name="xmlSeo">seoxml文档</param>
        /// <param name="tmpPathSeo">文档地址</param>
        void AddNodeByXML(XmlDocument xmlSeo, string tmpPathSeo) 
        {
            XmlText xmltext;
            xmlSeo = new XmlDocument();
            //加入XML的声明段落 
            XmlNode xmlnode = xmlSeo.CreateXmlDeclaration("1.0", "utf-8", null);
            xmlSeo.AppendChild(xmlnode);
            XmlElement xmlelem = xmlSeo.CreateElement("", "Root", "");
            xmltext = xmlSeo.CreateTextNode("");
            xmlelem.AppendChild(xmltext);
            xmlSeo.AppendChild(xmlelem);
            XmlDocument xmlDoc = new XmlDocument();
            string tmpPath = HttpContext.Current.Server.MapPath("~/VirtualPath.xml");
            xmlDoc.Load(tmpPath);
            XmlNodeList xmlNodeList = xmlDoc.SelectSingleNode("RewriterConfig").SelectSingleNode("urls").ChildNodes;
            for (int i = 0; i < xmlNodeList.Count; i++)
            {
                XmlNode node = xmlNodeList[i];
                XmlAttribute xmlabuu = null;
                try
                {
                    xmlabuu = node.Attributes["virtualUrl"];
                }
                catch (Exception)
                {
                    continue;
                }
                string tmp = xmlabuu.Value;
                if (!tmp.Contains("(") && !tmp.Contains(")") && !tmp.Contains("\""))
                {
                    tmp = tmp.Replace(".html", "");
                    tmp = tmp.Replace(".htm", "");
                    tmp = tmp.Replace(".aspx", "");
                    tmp = tmp.Replace("/", "");
                    XmlInsertNode(xmlSeo, tmpPathSeo, "Root", tmp, "title", "");
                    XmlInsertNode(xmlSeo, tmpPathSeo, "Root", tmp, "discription", "");
                    XmlInsertNode(xmlSeo, tmpPathSeo, "Root", tmp, "keywords", "");
                }
                else { continue; }

            }
            xmlSeo.Save(tmpPathSeo);
        }

        /// <summary> 
        /// 插入一个节点和此节点的字节点 
        /// </summary> 
        /// <param name="objXmlDoc">xml文档对象</param> 
        /// <param name="xmlPath">xml路径</param>
        /// <param name="MailNode">当前节点路径</param> 
        /// <param name="ChildNode">新插入节点</param> 
        /// <param name="Element">插入节点的子节点</param> 
        /// <param name="Content">子节点的内容</param> 
        public static void XmlInsertNode(XmlDocument objXmlDoc, string xmlPath, string MailNode, string ChildNode, string Element, string Content)
        {
            XmlNode objRootNode = objXmlDoc.SelectSingleNode(MailNode);
            XmlNode isNode = objXmlDoc.SelectSingleNode(MailNode).SelectSingleNode(ChildNode);
            if (isNode == null)
            {
                XmlElement objChildNode = objXmlDoc.CreateElement(ChildNode);
                objRootNode.AppendChild(objChildNode);
                XmlElement objElement = objXmlDoc.CreateElement(Element);
                objElement.InnerText = Content;
                objChildNode.AppendChild(objElement);
            }
            else
            {
                XmlElement objElement = objXmlDoc.CreateElement(Element);
                objElement.InnerText = Content;
                isNode.AppendChild(objElement);

            }
        } 
        #endregion
    }
}
我这里做的方式很简单。继承了一个httpmodule。为什么这样做。原因很简单。因为我要保证数据的及时更新。那么每次用户在访问我的时候我只会做一个简单的判断。该seo信息缓存里存在吗?我存放在xml数据里的数据进行了更改吗?如果数据存在缓存中,我这里不会做任何操作。我还验证存放seo的xml文件是否进行了更改,如果更改了,将缓存数据清空,重新加载。加载时候是根据URL重写地址文件来加载。如果没更改,那程序就不会进入相关的加载操作。所以,只有当更改seo文件和程序第一次运行时会加载数据,其他的时候都不会。所以,从效率上可以看出还是不错。ok。不存在的话就不用说了吧。

那我的xml数据格式是怎么样的呢?我这先贴出来我的url地址重写文件,大家看下

<RewriterConfig>
  <urls>
	<!--一级栏目-->
	<add virtualUrl="/index.html" destinationUrl="~/index.aspx"/>
    	<add virtualUrl="/About.html" destinationUrl="~/Abouttyj/AboutTYJ.aspx"/>
	<add virtualUrl="/News.html" destinationUrl="~/News/News.aspx"/>
	<add virtualUrl="/Advantage.html" destinationUrl="~/Advantage/Advantage.aspx"/>
	<add virtualUrl="/Culture.html" destinationUrl="~/Culture/Culture.aspx"/>
	<add virtualUrl="/Performance.html" destinationUrl="~/Performance/Performance.aspx"/>
	<add virtualUrl="/Order.html" destinationUrl="~/Order/Order.aspx"/>
	<add virtualUrl="/Feedback.html" destinationUrl="~/Feedback/Feedback.aspx"/>
	  <!--关于我们-->
	  <add virtualUrl="/About/Honor.html" destinationUrl="~/Abouttyj/Honor.aspx"/>
	  <add virtualUrl="/About/team.html" destinationUrl="~/Abouttyj/Team.aspx"/>
	  <add virtualUrl="/About/Customer.html" destinationUrl="~/Abouttyj/Customer.aspx"/>
	  <add virtualUrl="/About/Recruitment.html" destinationUrl="~/Abouttyj/Recruitment.aspx"/>
	  <add virtualUrl="/About/Contact.html" destinationUrl="~/Abouttyj/Contact.aspx"/>
	  <!--新闻动态-->
	  <add virtualUrl="/Freight.html" destinationUrl="~/News/Freight.aspx"/>
	  <add virtualUrl="/Industry.html" destinationUrl="~/News/Industry.aspx"/>
	  <add virtualUrl="/News/(\d+).html" destinationUrl="~/News/Newsdetail.aspx?name=$1"/>
	  <!--天翼捷优势-->
	  <add virtualUrl="/Fleet.html" destinationUrl="~/Advantage/Fleet.aspx"/>
	  <add virtualUrl="/Warehouse.html" destinationUrl="~/Advantage/Warehouse.aspx"/>
	  <!--天翼捷文化-->
	  <add virtualUrl="/Sentiment.html" destinationUrl="~/Culture/Sentiment.aspx"/>
	  <add virtualUrl="/Train.html" destinationUrl="~/Culture/Train.aspx"/>
	  <!--业绩展示-->
	  <add virtualUrl="/Logistics.html" destinationUrl="~/Performance/Logistics.aspx"/>
	  <add virtualUrl="/Logistics/(\d+).html" destinationUrl="~/Performance/LogisticsDetail.aspx?id=$1"/>
	  <add virtualUrl="/Performance/(\d+).html" destinationUrl="~/Performance/PerformanceDdetail.aspx?id=$1"/>
	  <!--在线订单-->
	  <add virtualUrl="/Order/(\d+).html" destinationUrl="~/Order/OrderDetailed.aspx?id=$1"/>
	  <add virtualUrl="/SeeOrder.html" destinationUrl="~/Order/SeeOrder.aspx"/>
	  <!--留言反馈-->
	  <add virtualUrl="/SeeFeedback.html" destinationUrl="~/Feedback/SeeFeedback.aspx"/>
	  <!--首页搜索-->
	  <add virtualUrl="/Logistics/(\w+)_(\w+)" destinationUrl="~/Performance/Logistics.aspx?city=$1&citys=$2"/>
	  <!--站点地图-->
	  <add virtualUrl="/sitemap.html" destinationUrl="~/siteMap.aspx"/>
  </urls>
</RewriterConfig>
上面我的url地址重写,下面是我根据url重写生成的seo.xml文件

<?xml version="1.0" encoding="utf-8"?>
<Root>
  <index>
    <title>
    </title>
    <discription>
    </discription>
    <keywords>
    </keywords>
  </index>
  <About>
    <title>
    </title>
    <discription>
    </discription>
    <keywords>
    </keywords>
  </About>
  <News>
    <title>
    </title>
    <discription>
    </discription>
    <keywords>
    </keywords>
  </News>
  <Advantage>
    <title>
    </title>
    <discription>
    </discription>
    <keywords>
    </keywords>
  </Advantage>
  <Culture>
    <title>
    </title>
    <discription>
    </discription>
    <keywords>
    </keywords>
  </Culture>
  <Performance>
    <title>
    </title>
    <discription>
    </discription>
    <keywords>
    </keywords>
  </Performance>
  <Order>
    <title>
    </title>
    <discription>
    </discription>
    <keywords>
    </keywords>
  </Order>
  <Feedback>
    <title>
    </title>
    <discription>
    </discription>
    <keywords>
    </keywords>
  </Feedback>
  <AboutHonor>
    <title>
    </title>
    <discription>
    </discription>
    <keywords>
    </keywords>
  </AboutHonor>
  <Aboutteam>
    <title>
    </title>
    <discription>
    </discription>
    <keywords>
    </keywords>
  </Aboutteam>
  <AboutCustomer>
    <title>
    </title>
    <discription>
    </discription>
    <keywords>
    </keywords>
  </AboutCustomer>
  <AboutRecruitment>
    <title>
    </title>
    <discription>
    </discription>
    <keywords>
    </keywords>
  </AboutRecruitment>
  <AboutContact>
    <title>
    </title>
    <discription>
    </discription>
    <keywords>
    </keywords>
  </AboutContact>
  <Freight>
    <title>
    </title>
    <discription>
    </discription>
    <keywords>
    </keywords>
  </Freight>
  <Industry>
    <title>
    </title>
    <discription>
    </discription>
    <keywords>
    </keywords>
  </Industry>
  <Fleet>
    <title>
    </title>
    <discription>
    </discription>
    <keywords>
    </keywords>
  </Fleet>
  <Warehouse>
    <title>
    </title>
    <discription>
    </discription>
    <keywords>
    </keywords>
  </Warehouse>
  <Sentiment>
    <title>
    </title>
    <discription>
    </discription>
    <keywords>
    </keywords>
  </Sentiment>
  <Train>
    <title>
    </title>
    <discription>
    </discription>
    <keywords>
    </keywords>
  </Train>
  <Logistics>
    <title>
    </title>
    <discription>
    </discription>
    <keywords>
    </keywords>
  </Logistics>
  <SeeOrder>
    <title>
    </title>
    <discription>
    </discription>
    <keywords>
    </keywords>
  </SeeOrder>
  <SeeFeedback>
    <title>
    </title>
    <discription>
    </discription>
    <keywords>
    </keywords>
  </SeeFeedback>
  <sitemap>
    <title>
    </title>
    <discription>
    </discription>
    <keywords>
    </keywords>
  </sitemap>
</Root>
这里是程序第一次运行根据我的源码规则生成的一个只有节点信息没有值得xml文件。那么数据怎么来。呵呵呵,这里就需要问你的seo专员了吧。呵呵呵

下面是我的SEOparamertes 类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Optimization_WebPage
{
    public class SEOParameters
    {
        public SEOParameters() 
        {

        }

        public SEOParameters(string _title,string _desprtion,string _keyWords,string _ecoding, string _authorContent, string _copyright,
            string _language, string _clientContent, string _urlRoobts)
        {
            _SEO_title = _title;
            _SEO_desprtion = _desprtion;
            _SEO_keyWords = _keyWords;
            _SEO_authorContent = _authorContent;
            _SEO_clientContent = _clientContent;
            _SEO_copyrightContent = _copyright;
            _SEO_urlRoobts = _urlRoobts;
            _SEO_languagestr = _language;
            _SEO_ecoding = _ecoding;
        }

        public SEOParameters(string _title,string _desprtion,string _keyWords) 
        {
            _SEO_title = _title;
            _SEO_desprtion = _desprtion;
            _SEO_keyWords = _keyWords;
        }
        string _SEO_title = "";
        /// <summary>
        /// 标题信息.该值不能为空.否则程序异常.且最多只能接受80个字符
        /// </summary>
        public string SEO_title
        {
            get { return _SEO_title.Length > 80 ? _SEO_title.Substring(0, 79) : _SEO_title; }
            set { _SEO_title = value; }
        }

        string _SEO_desprtion = "";

        /// <summary>
        /// 页面描述信息.该值不能为空.否则程序异常.且最多只能接受200个字符
        /// </summary>
        public string SEO_desprtion
        {
            get { return _SEO_desprtion.Length > 200 ? _SEO_desprtion.Substring(0, 199) : _SEO_desprtion; }
            set { _SEO_desprtion = value; }
        }
        string _SEO_keyWords = "";
        /// <summary>
        /// 页面关键词.该值不能为空.否则程序异常.且最多只能接受100个字符
        /// </summary>
        public string SEO_keyWords
        {
            get { return _SEO_keyWords.Length > 100 ? _SEO_keyWords.Substring(0, 99) : _SEO_keyWords; }
            set { _SEO_keyWords = value; }
        }

        string _SEO_ecoding = "";
        /// <summary>
        /// 编码方式.如果值为"".系统默认会设置值为:text/html;charset=utf-8
        /// </summary>
        public string SEO_ecoding
        {
            get { return _SEO_ecoding == "" ? "text/html;charset=utf-8" : _SEO_ecoding; }
            set { _SEO_ecoding = value;}
        }


        string _SEO_authorContent = "";
        /// <summary>
        /// 著作者:如果值为""。系统默认会设置值为:www.ay56.cn
        /// </summary>
        public string SEO_authorContent
        {
            get { return _SEO_authorContent == "" ? "http://www.ay56.cn" : _SEO_authorContent; }
            set { _SEO_authorContent = value; }
        }

        string _SEO_copyrightContent = "";
        /// <summary>
        /// 版权所有.如果值为""。系统默认会设置值为:www.ay56.cn
        /// </summary>
        public string SEO_copyrightContent
        {
            get { return _SEO_copyrightContent == "" ? "http://www.ay56.cn" : _SEO_copyrightContent; }
            set { _SEO_copyrightContent = value;}
        }

        string _SEO_languagestr = "";
        /// <summary>
        /// 网页语言:如果值为"",系统默认会设置值为:utf-8
        /// </summary>
        public string SEO_languagestr
        {
            get { return _SEO_languagestr == "" ? "utf-8" : _SEO_languagestr; }
            set { _SEO_languagestr = value; }
        }

        string _SEO_clientContent = "";
        /// <summary>
        /// 客户端HTML文件渲染器.如果值为"",系统默认会设置值为:IE=EmulateIE7
        /// </summary>
        public string SEO_clientContent
        {
            get { return _SEO_clientContent == "" ? "IE=EmulateIE7" : _SEO_clientContent; }
            set { _SEO_clientContent = value; }
        }

        string _SEO_urlRoobts = "";
        /// <summary>
        /// 搜苏引擎索引目录地址:如果存在该文件,给于文件路径.如果值为"",系统默认会设置值为:"all"
        /// </summary>
        public string SEO_urlRoobts
        {
            get { return _SEO_urlRoobts == "" ? "all" : _SEO_urlRoobts; }
            set { _SEO_urlRoobts = value; }
        }
    }
}
下面代码是对viewstate的移动和是否需要对空字符进行出来。就是对渲染出来的html结果排成类似于百度、google的源码那里。最大化限度减少文件的空白字符,增加传输速度。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text.RegularExpressions;


namespace Optimization_WebPage.ViewState
{
    /// <summary>
    /// 移动隐藏字段 __VIEWSTATE 到 /Form 之前.
    /// 作者:shawn
    /// </summary>
    public class MoveViewStateFilter : System.IO.MemoryStream {
        System.IO.Stream _filter;
        bool _filtered = false;

        /// <param name="filter">A reference to the downstream HttpResponse.Filter.</param>
        public MoveViewStateFilter( System.IO.Stream filter ) 
        {
            _filter = filter;
        }

        /// <summary>Closes this filter stream.</summary>
        /// <remarks>
        /// The contents of this filter are written to the downstream filter after the hidden
        /// __VIEWSTATE form field is moved.
        /// </remarks>
        public override void Close()
        {
            //获取针对该页面是否进行空字符优化处理操作
            bool OptimizationNuLLStr = HttpContext.Current.Cache["OptimizationNuLLStr"] != null ? (bool)HttpContext.Current.Cache["OptimizationNuLLStr"] : false;
            //获取针对该页面是否进行.NET代码移动操作
            bool MovieNetCode = HttpContext.Current.Cache["MovieNetCode"] != null ? (bool)HttpContext.Current.Cache["MovieNetCode"] : false;

            if (_filtered)
            {
                if (this.Length > 0)
                {
                    byte[] bytes = null; ;
                    string content = System.Text.Encoding.UTF8.GetString(this.ToArray());

                    string tmp = "http://" + HttpContext.Current.Request.Url.Host + "/";

                    if (MovieNetCode) //是否进行移动处理
                    {
                        if (content.Contains("<div class=\"aspNetHidden\""))
                        {
                            content = this.STRINGMOVE(content, "<div class=\"aspNetHidden\"", "</div>", "</form>");
                        }
                        else
                        {
                            content = this.STRINGMOVE(content, "<input type=\"hidden\" name=\"__VIEWSTATE\" id=\"__VIEWSTATE\"", "/>", "</form>");
                            content = this.STRINGMOVE(content, "<input type=\"hidden\" name=\"__EVENTVALIDATION\" id=\"__EVENTVALIDATION\"", "/>", "</form>");
                        }
                        content = this.STRINGMOVE(content, "<script src=\"/WebResource.axd?", "</script>", "</form>");
                        if (content.Contains("<script src=\"/ScriptResource.axd?"))
                        {
                            for (int i = 0; i < 3; i++)
                            {
                                content = this.STRINGMOVE(content, "<script src=\"/ScriptResource.axd?", "</script>", "</form>");
                            }
                        }

                        if (content.Contains("<script type=\"text/javascript\">\r\n//<![CDATA["))
                        {
                            for (int i = 0; i < 3; i++)
                            {
                                content = this.STRINGMOVE(content, "<script type=\"text/javascript\">\r\n//<![CDATA[", "//]]>\r\n</script>", "</form>");
                            }
                        }

                        content = this.STRINGMOVE(content, "<script type=\'text/javascript\'>new Sys.WebForms.Menu", "</script>", "</form>");
                    }
                    if (OptimizationNuLLStr) //是否进行空字符优化
                    {
                        多余字符替换为""
                        System.Text.RegularExpressions.Regex regex = new Regex(@"   ", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                        System.Text.RegularExpressions.Regex regextwo = new Regex(@"\r\n", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                        System.Text.RegularExpressions.Regex regexthree = new Regex(@"\r\n\t", System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                        content = regexthree.Replace(content, "");
                        content = regextwo.Replace(content, "");
                        content = regex.Replace(content, "");
                    }
                    bytes = System.Text.Encoding.UTF8.GetBytes(content);
                    _filter.Write(bytes, 0, bytes.Length);
                    tmp = null;
                    content = null;
                }
                _filter.Close();
            }
            base.Close();
        }

        /// <summary>
        /// 移动字符串
        /// </summary>
        /// <param name="content">渲染出来的内容</param>
        /// <param name="MoveString_start">要移动字符串的开始字符</param>
        /// <param name="MoveString_End">要移动字符串的结束字符</param>
        /// <param name="Insert_string">需要在哪个字符前插入你需要移动的字</param>
        /// <param name="tmpCount">要移动字符串的结束字符串的长度</param>
        string STRINGMOVE(string content, string MoveString_start, string MoveString_End, string Insert_string) 
        {
            int MoveStringIndex_start = content.IndexOf(MoveString_start);
            if (MoveStringIndex_start > 0)
            {
                int MoveStringIndex_End = content.IndexOf(MoveString_End, MoveStringIndex_start) + MoveString_End.Length;
                string MoviString = content.Substring(MoveStringIndex_start, MoveStringIndex_End - MoveStringIndex_start) + "\n";
                content = content.Remove(MoveStringIndex_start, MoveStringIndex_End - MoveStringIndex_start);
                int Insert_stringIndex = content.IndexOf(Insert_string);
                if (Insert_stringIndex >= 0)
                {
                    content = content.Insert(Insert_stringIndex, MoviString);
                    MoviString = null;
                    return content;
                }
            }
            return content;
        }


        public override void Write( byte[] buffer, int offset, int count )
        {
            if ( ( System.Web.HttpContext.Current != null )
              && ( "text/html" == System.Web.HttpContext.Current.Response.ContentType ) ) {
                base.Write( buffer, offset, count );
                _filtered = true;
            }
            else {
                _filter.Write( buffer, offset, count );
                _filtered = false;
            }
        }


        /// <summary>
        /// 便利渲染后的字符串。对其中的a标签和link标签的href进行重赋值
        /// </summary>
        /// 作者:shawn
        /// <param name="content">渲染出来的结果</param>
        /// <param name="tmp">标头字符串</param>
        string insertHostName(string content,string tmp) 
        {
            //该正则需优化
            //string reg = @"<a[^>]*href=(""(?<href>[^""]*)""|'(?<href>[^']*)'|(?<href>[^\s>]*))[^>]*>(?<text>[\s\S]*?)</a>";

            //逍遥
            //string reg = @"<\s*a\b(?![^<>]*?(javascript|__doPostBack))[^<>]+?href=(['""]?)(?<url>[^*#<>()]*?)\2[^>]*>";

            //string reg = @"(?i)<(a|link)\s[^>]*?href=(['""]?)(?!javascript|__doPostBack|alert)(?<url>[^'""\s*#<>()]+)[^>]*>";
            //string reg = @"(?i)<a\s[^>]*?href=(['""]?)(?!javascript|__doPostBack)(?<url>[^'""\s*#<>]+)[^>]*>";

            string reg = @"(?i)<(?:img\s[^>]*?(?<url>src=(['""]?)[^'""\s*#<>()]+\1)|(?:a|link)\s[^>]*?(?<url>href=(['""]?)(?!javascript|__doPostBack|alert)[^'""\s*#<>()]+\2))[^>]*>";
            MatchCollection mc1 = Regex.Matches(content, reg, RegexOptions.IgnoreCase | RegexOptions.Compiled);

            for (int i = 0; i < mc1.Count; i++)
            {
                string href_url = mc1[i].Groups["url"].Value;// 这里取到了href属性值

                //拼接后的url1
                //string href = "href=\"" + href_url + "\"";
                //string hreftwo = "href=" + href_url;

                if (!href_url.Contains(tmp) && !href_url.Contains("javascript") && !href_url.Contains("#") && !href_url.Contains("(")
                    && !href_url.Contains("__doPostBack") && !href_url.Contains("*") && !href_url.Contains("<") && href_url != "" &&
                    !href_url.Contains(")") && !href_url.Contains(">") && !href_url.Contains("http://"))
                {
                    content = this.Movie(href_url, content, tmp);
                }
            }
            return content;        
        }

        /// <summary>
        /// 删除插入替换法
        /// </summary>
        /// 作者:shawn
        /// <param name="href">链接</param>
        /// <param name="content">渲染的结果</param>
        /// <param name="tmp">标头</param>
        /// <param name="tmpInt">截取的index</param>
        /// <returns></returns>
        string Movie(string href,string content,string tmp) 
        {
            int StarIndex = content.IndexOf(href);
            if (StarIndex != -1)
            {
                int EndIndex = content.IndexOf(">", StarIndex);
                href = href.Replace("href","");
                href = href.Replace("=","");
                href = href.Replace("\"", "");
                if (href.IndexOf("../") == 0)
                {
                    href = href.Remove(0, 3);
                }
                else if (href.IndexOf("~/") == 0)
                {
                    href = href.Remove(0, 2);
                }
                else if (href.IndexOf("/") == 0 || href.IndexOf("~") == 0)
                {
                    href = href.Remove(0, 1);
                }
                content = content.Remove(StarIndex, EndIndex - StarIndex);
                content = content.Insert(StarIndex, "href=\"" + tmp + href + "\"");
                return content;
            }
            return content;
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;




namespace Optimization_WebPage.ViewState
{
    /// <summary>
    /// 注册移动事件.开始进行viewstate移动
    /// 作者:shawn
    /// </summary>
    public class MoveViewStateModule : System.Web.IHttpModule {
        public MoveViewStateModule()
        {


        }
        void System.Web.IHttpModule.Dispose() {
        }


        void System.Web.IHttpModule.Init( System.Web.HttpApplication context )
        {
            context.BeginRequest += new EventHandler( this.BeginRequestHandler );
        }


        void BeginRequestHandler( object sender, EventArgs e ) {
            System.Web.HttpApplication application = ( System.Web.HttpApplication )sender;
            application.Response.Filter = new MoveViewStateFilter( application.Response.Filter );
        }
    }
}
//如需使用BasePage.请再web应用的Global文件中对应的事件替换一下代码并导入命名空间using System.IO;
protected void Application_Start(object sender, EventArgs e)
{
    DirectoryInfo dir = new DirectoryInfo(this.Server.MapPath("~/App_Data/ViewState/"));
    if (!dir.Exists)
        dir.Create();
    else
    {
        DateTime nt = DateTime.Now.AddHours(-1);
        foreach (FileInfo f in dir.GetFiles())
        {
            if (f.CreationTime < nt)
                f.Delete();
        }
    }


}
有朋友问我你为什么不写在Application_Start事件来加载数据。还是那个回答,数据的及时性。我的缓存数据是根据xml做的缓存、如果xml一旦修改。数据会重新加载。

别忘了、这个是配合url地址重写用的。所以我们还需要做一件事情:

using System;
using System.Web;
using System.Configuration;
using System.Xml.Serialization;
using System.Web.Caching;


namespace Module.config
{
    [Serializable()]
    [XmlRoot("RewriterConfig")]
    public class UrlConfiguration
    {
        public UrlConfiguration() { }


        /// <summary>
        /// 返回配置文件中的RewriterConfig配置节.提示信息.该数据缓存依赖于文件
        /// </summary>
        /// <returns></returns>
        public static UrlConfigurationSection GetConfig()
        {
            if (HttpContext.Current.Cache["RewriterConfig"] == null)
            {
                HttpContext.Current.Cache.Insert("RewriterConfig", ConfigurationManager.GetSection("RewriterConfig"), new CacheDependency(HttpContext.Current.Server.MapPath("~/VirtualPath.xml")));
                HttpContext.Current.Cache.Insert("IsSetSeoXmlByVirtualPath", "Yes");
            }
            else 
            {
                if (HttpContext.Current.Cache["IsSetSeoXmlByVirtualPath"] != null)
                {
                    HttpContext.Current.Cache["IsSetSeoXmlByVirtualPath"] = "No";
                }
                else 
                {
                    HttpContext.Current.Cache.Insert("IsSetSeoXmlByVirtualPath", "No");
                }
            }
            return (UrlConfigurationSection)HttpContext.Current.Cache["RewriterConfig"];  
        }
    }
}

至此。已经写完了。其实这个东西很早了,已经很多站在使用。最后你还可以开发一个管理的一个页面对xml进行管理。很方面。呵呵呵。很多还不完善,需要大家一起来完善。








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ASP.NET ViewState 是一种用于Web 应用程序中跨请求存储数据的机制。以下是一个使用 ViewState 的示例: 假设您有一个页面,其中包含一个文本框和一个按钮。用户在文本框中输入一些文本,然后单击按钮。在单击按钮时,将在服务器端处理程序中使用 ViewState 存储文本框中的值,并在页面上显示它。 以下是一个简单的 ASP.NET 页面代码示例,它演示了如何使用 ViewState 存储和检索文本框中的值: ```html <%@ Page Language="C#" %> <!DOCTYPE html> <html> <head runat="server"> <title>ViewState Example</title> </head> <body> <form id="form1" runat="server"> <div> <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox> <br /> <asp:Button ID="Button1" runat="server" Text="Save" OnClick="Button1_Click" /> <br /> <asp:Label ID="Label1" runat="server"></asp:Label> </div> </form> </body> </html> ``` 在按钮单击事件处理程序中,我们将文本框中的值存储在 ViewState 中,并将其显示在页面上: ```csharp protected void Button1_Click(object sender, EventArgs e) { string text = TextBox1.Text; ViewState["myText"] = text; Label1.Text = "Text saved: " + text; } ``` 在页面加载事件处理程序中,我们检索存储在 ViewState 中的值,并将其显示在页面上: ```csharp protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { if (ViewState["myText"] != null) { string text = (string)ViewState["myText"]; Label1.Text = "Text retrieved: " + text; } } } ``` 通过这种方式,我们可以在页面上保留用户在文本框中输入的值,即使用户单击其他按钮或导航到其他页面。请注意,ViewState 可能会增加页面大小,并增加网络传输时间。因此,我们应该谨慎使用 ViewState,并仅在必要时使用它。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值