[转载]Json.Net 学习笔记(一) - 资源收集 - 博客园

mikel阅读(1055)

[转载]Json.Net 学习笔记(一) – 资源收集 – 博客园.

使用Newtonsoft.Json这是一个开源的Json.Net库。

下载地址:http://json.codeplex.com/releases/view/50552。当前版本为 Release 8

从下载到的源代码中获取Newtonsoft.Json.Net20.dll,添加到自己的工程中。

using Newtonsoft.Json;

定义类:

 public class Message
{
public string Address { get; set; }
[JsonProperty(TypeNameHandling = TypeNameHandling.All)]
public object Body { get; set; }
}
public class SearchDetails
{
public string Query { get; set; }
public string Language { get; set; }
}

测试:

           Message message = new Message
{
Address = “http://google.com“,
Body = new SearchDetails { Query = “Json.Net”, Language = “en-us” }
};
string jsonMsg = JsonConvert.SerializeObject(message, Formatting.Indented);//Indented表示以缩进形式显示结果
System.Diagnostics.Debug.Write(jsonMsg);
Message deserialized = JsonConvert.DeserializeObject<Message>(jsonMsg);
SearchDetails searchDetails = (SearchDetails)deserialized.Body;
Response.Write(searchDetails.Query + “,” + searchDetails.Language + “<br/>”);

Debug输出结果格式:

{
“Address”: “http://google.com“,
“Body”: {
“$type”: “TestJsonSerialization.SearchDetails, TestJsonSerialization”,
“Query”: “Json.Net”,
“Language”: “en-us”
}
}

注:1.JsonProperty标记字段或属性,用来控制它作为一个Json对象的属性序列化。

       2.TypeNameHandling 用来为Json序列化指定类型名。它有几个枚举值:

Member Description
None Do not include the .NET type name when serializing types.
Objects Include the .NET type name when serializing into a JSON object structure.
Arrays Include the .NET type name when serializing into a JSON array structure.
Auto Include the .NET type name when the type of the object being serialized is not the same as its declared type.
All Always include the .NET type name when serializing.

[转载]C# 序列化与反序列化几种格式的转换 - 深山居士 - 博客园

mikel阅读(994)

[转载]C# 序列化与反序列化几种格式的转换 – 深山居士 – 博客园.

这里介绍了几种方式之间的序列化与反序列化之间的转换

首先介绍的如何序列化,将object对象序列化常见的两种方式即string和xml对象;

第一种将object转换为string对象,这种比较简单没有什么可谈的;

 

 public string ScriptSerialize<T>(T t)
        {
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            return serializer.Serialize(t);
        }

第二种将object转换为xml对象:

public string ScriptSerializeToXML<T>(T t)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(T));
            MemoryStream mem = new MemoryStream();
            XmlTextWriter writer = new XmlTextWriter(mem,Encoding.UTF8);
            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
            ns.Add("","");
            serializer.Serialize(writer,t,ns);
            writer.Close();
            return Encoding.UTF8.GetString(mem.ToArray());
        }

下面我主要讲string对象反序列化为对应的对象;

一、将string对象反序列化为object对象

public T ScriptDeserialize<T>(string strJson)
        {
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            return serializer.Deserialize<T>(strJson);
        }

二、将string对象反序列化为list对象

 public List<T> JSONStringToList<T>(string strJson)
        {
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            List<T> objList = serializer.Deserialize<List<T>>(strJson);
            return objList;
        }

三、将string对象反序列化为datatable对象

public DataTable JSONStringToDataTable<T>(string strJson)
        {
            DataTable dt = new DataTable();
            if (strJson.IndexOf("[") > -1)//如果大于则strJson存放了多个model对象
            {
                strJson = strJson.Remove(strJson.Length - 1, 1).Remove(0, 1).Replace("},{", "};{");
            }
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            string[] items = strJson.Split(';');

            foreach (PropertyInfo property in typeof(T).GetProperties())//通过反射获得T类型的所有属性
            {
                DataColumn col = new DataColumn(property.Name,property.PropertyType);
                dt.Columns.Add(col);
            }
            //循环 一个一个的反序列化
            for (int i = 0; i < items.Length; i++)
            {
                DataRow dr = dt.NewRow();
                //反序列化为一个T类型对象
                T temp = serializer.Deserialize<T>(items[i]);
                foreach (PropertyInfo property in typeof(T).GetProperties())
                {
                    dr[property.Name] = property.GetValue(temp,null);
                }
                dt.Rows.Add(dr);
            }
            return dt;
        }

四、将xml对象反序列化为object对象

public T JSONXMLToObject<T>(string strJson)
        {
            XmlDocument xdoc = new XmlDocument();
            try
            {
                xdoc.LoadXml(strJson);
                XmlNodeReader reader = new XmlNodeReader(xdoc.DocumentElement);
                XmlSerializer ser = new XmlSerializer(typeof(T));
                object obj = ser.Deserialize(reader);
                return (T)obj;
            }
            catch
            {
                return default(T);
            }
        }

现在用具体的实例来如何调用他们呢?特别要注意的是将xml对象反序列化objcet对象

 public class LoginObject
    {
          public string Account { get; set;}
          public string Password { get; set;}
     }
LoginObject loginObject = new LoginObject { Account = account, Password = password };
             ExTools.Manage.Class.CScriptSerialize Serialize = new Class.CScriptSerialize();
             //将object对象转换为string
              string strJson=Serialize.ScriptSerialize(loginObject);
           
             //将object对象转换为xml对象
             string strJson = Serialize.ScriptSerializeToXML(loginObject);
            
 
             //转换为list对象
              List<LoginObject> list = Serialize.JSONStringToList<LoginObject>(strJson);
             //将一个xml对象转换为object对象
            strJson = strJson.Substring(1, strJson.Length - 1);
             loginObject = Serialize.JSONXMLToObject<LoginObject>(strJson);
             //将字符串转换为dataTable
             DataTable dt = Serialize.JSONStringToDataTable<LoginObject>(strJson);
             //将字符串转换为object对象
             loginObject = Serialize.ScriptDeserialize<LoginObject>(strJson);

[转载]C#中的Json的序列化和反序列化 - chen110xi - 博客园

mikel阅读(1457)

[转载]C#中的Json的序列化和反序列化 – chen110xi – 博客园.

Json是一种通用的数据格式,我们在数据交换的时候,经常会用到,下面介绍C#中的 json序列化和反序列化,当然也可用在ASP.NET,silverlight,wpf中。我们在下面实例讲解如何进行Json的序列化和反序列化,本 文介绍两种方案,.net 3.5原生Json操作和Json.net中的Json操作。

首先,我们先建立一个测试对象,用来序列化和反序列化。

 

public class Person

{

public int ID { get; set; }

public string Name { get; set; }

public int Age { get; set; }

public DateTime BirthDay { get; set; }

}

第 一种,利用.Net Framework 3.5中原生的Json操作类库,特点就是不需要导入第三方类库,比较方便,速度上一般,而且需要.Net Framework的支持,我们知道现在还有很多服务器没有升级到.Net Framework 3.5,就用不了这个了。

首先导入下面类库,并加入下面代码
System.ServiceModel
System.ServiceModel.Web

 

class Program

{

static void Main(string[] args)

{

//创建测试对象

Person p = new Person();

p.ID = 1;

p.Name = "张三";

p.Age = 20;

p.BirthDay = DateTime.Now.AddYears(-20);

//将对象转化成Json字符串

DataContractJsonSerializer ds = new DataContractJsonSerializer(typeof(Person));

using (MemoryStream ms = new MemoryStream())

{

ds.WriteObject(ms, p);

string output = Encoding.UTF8.GetString(ms.ToArray());

Console.WriteLine(output);

}

}

}

输出结果

这个是.Net Framework 3.5原生的序列化方式,接着,我们介绍反序列化方式,还是同样的加入下面代码

 

class Program

{

static void Main(string[] args)

{

//创建测试对象

Person p = new Person();

p.ID = 1;

p.Name = "张三";

p.Age = 20;

p.BirthDay = DateTime.Now.AddYears(-20);

//将对象转化成Json字符串

string output = string.Empty;

DataContractJsonSerializer ds = new DataContractJsonSerializer(typeof(Person));

using (MemoryStream ms = new MemoryStream())

{

ds.WriteObject(ms, p);

output = Encoding.UTF8.GetString(ms.ToArray());

}

//将Json字符串转化成对象

DataContractJsonSerializer outDs = new DataContractJsonSerializer(typeof(Person));

using (MemoryStream outMs = new MemoryStream(Encoding.UTF8.GetBytes(output)))

{

Person outPerson = outDs.ReadObject(outMs) as Person;

Console.WriteLine("ID:" + outPerson.ID);

Console.WriteLine("Name:" + outPerson.Name);

Console.WriteLine("Age:" + outPerson.Age);

Console.WriteLine("Birthday:" + outPerson.BirthDay);

}

}

}

输出结果

我 们从.Net Framework 3.5原生的Json序列化及反序列化方式中,可以看出,还是相当麻烦的。很多网友也会问如果是.Net Framework 2.0该怎么办呢?下面,我们介绍一个第三方的Json序列化和反序列化类库,来完成上面操作,这个类库是有.Net Framework 2.0的版本的哦,而且这个类库还可以支持xml的序列化和反序列化操作(本文不做讲解)。下面看操作。

 

class Program

{

static void Main(string[] args)

{

//创建测试对象

Person p = new Person();

p.ID = 1;

p.Name = "张三";

p.Age = 20;

p.BirthDay = DateTime.Now.AddYears(-20);

//将对象转化成Json字符串

string output = JsonConvert.SerializeObject(p);

Console.WriteLine(output);

}

}

输出结果

这个是Json序列化方法,是不是简单了很多呢?

 

class Program

{

static void Main(string[] args)

{

//创建测试对象

Person p = new Person();

p.ID = 1;

p.Name = "张三";

p.Age = 20;

p.BirthDay = DateTime.Now.AddYears(-20);

//将对象转化成Json字符串

string output = JsonConvert.SerializeObject(p);

//将Json字符串转化成对象

Person outPerson = JsonConvert.DeserializeObject<Person>(output);

Console.WriteLine("ID:" + outPerson.ID);

Console.WriteLine("Name:" + outPerson.Name);

Console.WriteLine("Age:" + outPerson.Age);

Console.WriteLine("Birthday:" + outPerson.BirthDay);

}

}

输出结果

这个是Json反序列化方法,简单吧,而且据说这个类库的速度比.Net原生的Json序列化和反序列化方法要快很多。下载地址http://json.codeplex.com/

原创文章,转载请注明: 转载自.NET开发者

本文链接地址: c#中的Json的序列化和反序列化

文章的脚注信息由WordPress的wp-posturl插件自动生成

Related posts:

  1. Javascript中的Json序列化和反序列化
  2. JSON数据格式详解
  3. Json第三方类库Json.Net,声称超过其他Json序列化机制

[原创]ASP.NET MVC调用美图秀秀开放平台拼图实现

mikel阅读(1779)

项目中涉及到图片的美化和拼接的功能,于是用了美图秀秀开放平台的api

美图秀秀开放平台地址:http://open.web.meitu.com/

具体步骤如下:

1.创建MeiTuUpload.aspx视图页面:

页面代码:


<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>图片编辑</title>
    <% List<NewTang.Models.Entity.PicInfo> pics = new List<NewTang.Models.Entity.PicInfo>();
       if (ViewData["Pics"] != null)
       {
            pics=(List<NewTang.Models.Entity.PicInfo>)ViewData["Pics"];
       }

         %>
 <script src="http://open.web.meitu.com/sources/xiuxiu.js" type="text/javascript"></script>
<script language="javascript" type="text/javascript" >
window.onload=function(){
    xiuxiu.setFlashvars("localFileEnabled", 1);
	xiuxiu.embedSWF("altContent",2,"100%","100%");
	/*第1个参数是加载编辑器div容器,第2个参数是编辑器类型,第3个参数是div容器宽,第4个参数是div容器高*/

	xiuxiu.setUploadURL("http://localhost:4657/Components/stream.ashx"); //修改为您自己的上传接收图片程序
	xiuxiu.onInit = function ()
	{
	    <% if(pics.Count>0){ %>
		xiuxiu.loadPhoto("<%=pics[0].Path %>");
		<%} %>
	}
	xiuxiu.onUploadResponse = function (data)
	{
		 //alert("上传响应" + data);
		 parent.setfilePath(data);
		 parent.meitu.close();
	}
	xiuxiu.onClose = function() {
	    parent.meitu.close();
	}
}

    function closewbox() {

    }

    function setfilePath(data)
    {

    }
</script>
<style type="text/css">
	html, body { height:100%; overflow:hidden; }
	body { margin:0; }
</style>
</head>
<body >
<form id="upload" action="/Shop/UpLoadImage" method="post"
enctype="multipart/form-data">
<div id="altContent">

	<h1>美图秀秀</h1>
</div>
</form>
</body>
</html>

2.创建MeiTuUpload的Action
代码如下:

        /// <summary>
        /// 美图秀秀拼图
        /// </summary>
        /// <param name="newsInfoId"></param>
        /// <returns></returns>
        public ActionResult MeiTuUpload(string newsInfoId)
        {
            try
            {
                ViewData["title"] = "美图拼图";
                PicInfo pic = new PicInfo();
                pic.NewsInfoId = newsInfoId;
                ViewData["Pics"] = business.Select<PicInfo>(pic);
                //主题信息
                NewsInfo news = new NewsInfo() { NewsInfoID=newsInfoId };
                ViewData["News"] = business.Select<NewsInfo>(news);

            }
            catch (Exception e)
            {
                return new BaseController().Error("Error", "错误信息", e.Message);
            }
            return View();

        }

3.创建文件上传stream.ashx文件,可以从官方下载:备注:setUploadURL(“”) 参数为接收图片文件。php示例可参考 流式上传 或者 标准表单上传C#示例可参考 流式上传 或者 标准表单上传
代码如下:

using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Configuration;
using System.IO;
using System.Drawing;
using XiuXiuWeb.XiuXiuStream;

namespace XiuXiuWeb
{
    /// <summary>
    /// Summary description for stream
    /// </summary>
    public class stream : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            //config 配置节点可以将图片保存至指定目录,未配置将保存至 /XiuXiuUpload
            //<appSettings>
            //  <add key="XiuXiuImageSavePath" value="/upload"/>
            //</appSettings>
            string name = null;
            if (context.Request.TotalBytes > 0)
            {
                XiuXiuStreamImage img = new XiuXiuStreamImage(context);
                name = img.Save();
            }
            else
            {
                name = "非法访问";
            }
            context.Response.ContentType = "text/plain";
            context.Response.Write(name);
        }

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

    namespace XiuXiuStream
    {

        /// <summary>
        /// 上传抽象类
        /// </summary>
        public abstract class XiuXiuImage
        {

            public String ImageUrl { get;set;}
            /// <summary>
            /// 基类保存
            /// </summary>
            /// <returns>返回保存路径+文件名</returns>
            public virtual string Save()
            {
                string fileName = this.GetFileName();
                if (null == fileName) return null;

                //string root = HttpContext.Current.Server.MapPath(path);
                string thisDate = "";
                thisDate = DateTime.Now.Year.ToString();
                if (DateTime.Now.Month < 10)
                {
                    thisDate += "0" + DateTime.Now.Month.ToString();
                }
                else
                {
                    thisDate += DateTime.Now.Month.ToString();
                }
                if (DateTime.Now.Day < 10)
                {
                    thisDate += "0" + DateTime.Now.Day.ToString();
                }
                else
                {
                    thisDate += DateTime.Now.Day.ToString();
                }
                string relativePath = System.Web.HttpContext.Current.Server.MapPath(ConfigurationSettings.AppSettings["UploadDirectory"] + "pic/" + thisDate.ToString().Replace(" ", ""));
                if (!Directory.Exists(relativePath))
                {
                    Directory.CreateDirectory(relativePath);
                }
                //if (!Directory.Exists(root))
                //{
                //    Directory.CreateDirectory(root);
                //}
                this.ImageUrl=ConfigurationSettings.AppSettings["WebSiteUrl"] + "/UploadFiles/pic/" + thisDate.ToString().Replace(" ", "") + "/" + fileName;

                this.FileName = Path.Combine(relativePath, fileName);
                string[] paths = { relativePath, fileName };
                return string.Join("/", paths);
            }

            public XiuXiuImage()
            {
                path = path == null ? "/XiuXiuUpload" : path;
            }

            /// <summary>
            /// 确定上传类型
            /// </summary>
            protected bool IsUplodType
            {
                get
                {
                    string extension = this.GetExtension();
                    return ".jpg .gif .png .icon .bmp .tiff .wmf .emf .exif".IndexOf(extension) >= 0 ? true : false;
                }
            }
            private string _fileName = null;
            /// <summary>
            /// 最终保存路径
            /// </summary>
            protected string FileName
            {
                set { _fileName = value; }
                get { return _fileName; }
            }

            /// <summary>
            /// 配置文件路径 无配置上传到XiuXiuUpload
            /// </summary>
            protected string path = ConfigurationManager.AppSettings["UploadDirectory"];

            /// <summary>
            /// 获取拓展名
            /// </summary>
            /// <returns></returns>
            protected abstract string GetExtension();

            /// <summary>
            /// 获取最终保存文件名
            /// </summary>
            /// <returns></returns>
            protected string GetFileName()
            {
                string extension = this.GetExtension();
                if (null == extension) return null;
                else
                {
                    string name = this.GetName();
                    string[] imgName = { "news", name, extension };
                    return string.Join("", imgName);
                }
            }
            /// <summary>
            /// 获取保存文件名
            /// </summary>
            /// <returns></returns>
            private string GetName()
            {
                DateTime uploadTime = DateTime.Now;
                string[] times = { uploadTime.Year.ToString(), uploadTime.Month.ToString(), uploadTime.Day.ToString(),
                                 uploadTime.Hour.ToString(), uploadTime.Millisecond.ToString(), uploadTime.Second.ToString() };
                return string.Join("", times);
            }
        }
        /// <summary>
        /// Stream接收
        /// </summary>
        public sealed class XiuXiuStreamImage : XiuXiuImage
        {
            private MemoryStream stream = null;

            //图片的url路径
            private String webPath=null;

            public XiuXiuStreamImage(HttpContext context)
            {
                int count = context.Request.TotalBytes;
                if (count > 0)
                {
                    byte[] bytes = context.Request.BinaryRead(context.Request.TotalBytes);
                    this.stream = new MemoryStream(bytes);
                }
            }

            private Image File
            {
                get
                {
                    return this.stream == null ? null : Image.FromStream(this.stream);
                }
            }
            /// <summary>
            /// 保存图片,成功返回文件路径,失败null
            /// 非图片格式返回错误信息
            /// </summary>
            /// <returns>成功返回文件路径 失败null</returns>
            public override string Save()
            {
                if (!this.IsUplodType)
                {
                    this.stream.Dispose();
                    return "Only allowed to upload pictures.";
                }
                string returnName = base.Save();
                if (this.FileName != null)
                {
                    this.File.Save(this.FileName);
                    this.stream.Dispose();
                    return ImageUrl;
                }
                return null;
            }

            protected override string GetExtension()
            {
                if (this.File != null)
                {
                    string fileExtension = this.File.RawFormat.ToString().Substring(14),
                           jpgExtension = System.Drawing.Imaging.ImageFormat.Jpeg.Guid.ToString(),
                           gifExtension = System.Drawing.Imaging.ImageFormat.Gif.Guid.ToString(),
                           pngExtension = System.Drawing.Imaging.ImageFormat.Png.Guid.ToString(),
                           iconExtension = System.Drawing.Imaging.ImageFormat.Icon.Guid.ToString(),
                           bmpExtension = System.Drawing.Imaging.ImageFormat.Bmp.Guid.ToString(),
                           tiffExtension = System.Drawing.Imaging.ImageFormat.Tiff.Guid.ToString(),
                           wmfExtension = System.Drawing.Imaging.ImageFormat.Wmf.Guid.ToString(),
                           emfExtension = System.Drawing.Imaging.ImageFormat.Emf.Guid.ToString(),
                           exifExtension = System.Drawing.Imaging.ImageFormat.Exif.Guid.ToString();
                    fileExtension = fileExtension.Substring(0, fileExtension.Length - 1);
                    if (fileExtension == jpgExtension)
                    {
                        return ".jpg";
                    }
                    else if (fileExtension == gifExtension)
                    {
                        return ".gif";
                    }
                    else if (fileExtension == pngExtension)
                    {
                        return ".png";
                    }
                    else if (fileExtension == iconExtension)
                    {
                        return ".icon";
                    }
                    else if (fileExtension == bmpExtension)
                    {
                        return ".bmp";
                    }
                    else if (fileExtension == tiffExtension)
                    {
                        return ".tiff";
                    }
                    else if (fileExtension == wmfExtension)
                    {
                        return ".wmf";
                    }
                    else if (fileExtension == emfExtension)
                    {
                        return ".emf";
                    }
                    else if (fileExtension == exifExtension)
                    {
                        return ".exif";
                    }
                }
                return null;
            }
        }
    }
}

4.调用页面,重点在这儿,官方用的是prettify.js的弹窗,我用的wbox.js的iframe加载MeiTuUpload.aspx页面来实现的调用,官方封装了个插件用于执行示例代码来动态加载美图秀秀插件,下面是代码:
页面代码:

   <tr>
    <td class="bg1" height="25" align="right">缩略图:</td>
    <td class="bg2"><img id="imgNewsInfo" src="<%=newsInfo.NewsInfoImage %>" width="220" height="200" />
   </td>
  </tr>
   <tr>
    <td class="bg1" height="25" align="right">缩略图上传:</td>
    <td class="bg2"><input type="hidden" id="filePath" name="filePath" value="<%=newsInfo.NewsInfoImage %>" /><a id="meitu" class="btngreen" href="javascript:;">拼图</a>
   </td>
  </tr>

js弹窗代码:

    var meitu = $("#meitu").wBox({ noTitle:true,title: "拼图", requestType: "iframe", iframeWH: { width: 420, height: 400 }, target: "/NewsInfoManager/MeiTuUpload?InfoClass=2&newsInfoId=<%=newsInfo.NewsInfoID %>" });
    //设置返回值的路径
    function setfilePath(data) {
        $('#filePath').val(data);
        $('#imgNewsInfo').attr('src',data);
    }

[转载]lucene .NET 搜索图片 功能实现 - searchDM - 博客园

mikel阅读(891)

[转载]lucene .NET 搜索图片 功能实现 – searchDM – 博客园.

关于搜索部分

 1想建立索引。构建jpg图片解析器,在索引时将jpg图片的exif信息及其文本信息如名称,存放路径,大小,日期等等加入索引!具体实现代码如下:

public void BulidIndex(string path)//创建索引

        {

            DateTime biStart = DateTime.Now;//创建索引开始

            DirectoryInfo[] ChildDirectory;//子目录集

            FileInfo[] files;//当前所有文件

            DirectoryInfo FatherDirectory = new DirectoryInfo(path); //当前目录

            ChildDirectory = FatherDirectory.GetDirectories(“*.*”); //得到子目录集

            files = FatherDirectory.GetFiles(“*.jpg”);//得到jpg文件集,可以进行操作

 

            Analyzer analyzer = new MyAnalyzer();//声明一个分词器,

IndexWriter indexWriter = new IndexWriter(“index”, analyzer, true);/*建立一个IndexWriter的实例,这个类是负责创建索引的,有很多构造函数,这里使用的是其中的一个。三个参数分别是:索引建立到哪个目录,用什么分词器,还有就是是否创建。如果是否创建为false,那么就是以增量的方式来创建。*/

            for (int i = 0; i < files.Length; i++)

            {

                string maker = “unkown”, explord = “unkown”,

                       iso = “unkown”, aperture = “unkown”, focalLength=“unkown”;

                Document doc = new Document();//声明一个document并将图片的名称,存放路径,大小,日期,

                                             相机制造商,曝光度,ISO,焦距,光圈值依次通过field 添加入document中。

 

                FindExifinfo(files[i].FullName, ref maker, ref explord, ref iso, ref focalLength, ref aperture);

                doc.Add(new Field(“Name”, files[i].Name, Field.Store.YES, Field.Index.TOKENIZED));

                doc.Add(new Field(“FullName”, files[i].FullName, Field.Store.YES, Field.Index.NO));

                doc.Add(new Field(“Length”, files[i].Length.ToString(), Field.Store.YES, Field.Index.NO));

                doc.Add(new Field(“LastWriteTime”, files[i].LastWriteTime.ToString(), Field.Store.YES, Field.Index.NO));

                doc.Add(new Field(“CreationTime”, files[i].CreationTime.ToString(), Field.Store.YES, Field.Index.NO));

                doc.Add(new Field(“Maker”, maker, Field.Store.YES, Field.Index.UN_TOKENIZED));

                doc.Add(new Field(“Explord”, explord, Field.Store.YES, Field.Index.UN_TOKENIZED));

                doc.Add(new Field(“ISO”, iso, Field.Store.YES, Field.Index.UN_TOKENIZED));

                doc.Add(new Field(“FocalLength”, focalLength, Field.Store.YES, Field.Index.UN_TOKENIZED));

                doc.Add(new Field(“Aperture”, aperture, Field.Store.YES, Field.Index.UN_TOKENIZED));

   indexWriter.AddDocument(doc); /*调用了AddDocument方法,在AddDocument方法中,先组织一个Docuement对象,然后把这个对象交给IndexWriter*/

 

            }

 

            indexWriter.Optimize();//Optimize优化索引           

indexWriter.Close();//最后关闭创建过程

            DateTime biStop = DateTime.Now;//创建索引结束

            this.status1.Text = 创建索引用时: + (biStop – biStart).TotalSeconds + ;

        }

2 执行搜索并获取结果:

 private void button1_Click(object sender, EventArgs e)

        {

 

            listView1.Items.Clear();

            Hits hits = null;

            Query query = null;

            Analyzer analyzer = new MyAnalyzer();

            DateTime Start = DateTime.Now;//索引开始时间

            string TEXT= this.tbkey.Text;

            BooleanQuery BQ = new BooleanQuery( );   //使用Boolean 查询  

            if (TEXT == “”)

                return;

            try

            {

              switch (this.comboBox1.SelectedIndex)

                {

                    case 0:

                        QueryParser parser = new QueryParser(“Name”, analyzer);

                        query = parser.Parse(tbkey.Text);

     

                        break;

                    case 1: //使用Boolean 查询含有某个关键词或其他关键词 should 表示“或”的关系

                        Term T2 = new Term(“Maker”, TEXT);

                        TermQuery q2 = new TermQuery(T2);

                        BQ.Add(q2, BooleanClause.Occur.SHOULD);

                        break;

                    case 2: //按照片的ISO速率进行搜索

                        Term T3 = new Term(“ISO”, TEXT);

                        TermQuery q3 = new TermQuery(T3);

                        BQ.Add(q3, BooleanClause.Occur.SHOULD);

                        break;

                    case 3: //按照片的 曝光度进行搜索

                        Term T4 = new Term(“Explord”, TEXT);

                        TermQuery q4 = new TermQuery(T4);

                        BQ.Add(q4, BooleanClause.Occur.SHOULD);

                        break;

                    case 4: //按照片的 焦距进行搜索

                        Term T5 = new Term(“FocalLength”, TEXT);

                        TermQuery q5 = new TermQuery(T5);

                        BQ.Add(q5, BooleanClause.Occur.SHOULD);

                        break;

                    case 5: //按照片的光圈进行搜索

                        Term T6 = new Term(“Aperture”, TEXT);

                        TermQuery q6 = new TermQuery(T6);

                        BQ.Add(q6, BooleanClause.Occur.SHOULD);

                        break;

                    default: break;

               

                }

            }

            catch (Exception)

            {

                throw;

            }

 

            IndexSearcher searcher = new IndexSearcher(“index”);

 

            if (searcher != null)

            {

                if( 0 == this.comboBox1.SelectedIndex) //使用if语句对搜索方式进行分类,如果是按照相片或图片名称进行搜索则进行关键字匹配查询

                    hits = searcher.Search(query);

                else

                    hits = searcher.Search(BQ); //如果不是按名称搜索,则进行严格匹配查询搜索!

 

                if (hits.Length() > 0)

                {

                    this.status1.Text = ” 共检索 + hits.Length().ToString() + 个对象;

                }

                this.imageList.Images.Clear();

                for (int i = 0; i < hits.Length(); i++)

                { //将搜索结果分别添加入listview和imagelist中,此过程比较耗时间!无奈!!!

                    Document doc = hits.Doc(i);

                    int itemNumber = this.listView1.Items.Count;

                    //string fullname = doc.Get(“FullName”);

                  string[] subItem = { doc.Get(“Name”), doc.Get(“FullName”), (Convert.ToInt32(doc.Get(“Length”)) >> 10).ToString() + “KB”, doc.Get(“LastWriteTime”) }; //使用右移 加快程序的执行速度!

                  this.imageList.Images.Add(doc.Get(“FullName”), Bitmap.FromFile(doc.Get(“FullName”)));

                  this.listView1.Items.Add(new ListViewItem(subItem, doc.Get(“FullName”)));//显示结果较慢的元凶!

                }

            }

            else

            {

                this.status1.Text = ” 共检索 0 个对象;

            }

 

            DateTime Stop = DateTime.Now;//索引完成时间

            this.status1.Text += 搜索用时: + (Stop – Start).TotalSeconds + ;

运行效果图:

版本高于所引用的程序集“System.Web.Abstractions

mikel阅读(2368)

类库编译时提示:

错误    166    程序集“xxx.Controllers.Store, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null”所使用的“System.Web.Abstractions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”版本高于所引用的程序集“System.Web.Abstractions, Version=0.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”的版本    f:\Tang\xxx.Controllers.Store\bin\Debug\xxx.Controllers.Store.dll    Controllers.News

需要将xxx.Controller.News的引用的System.Web.Abstractions的版本重新引用下就行了

未能加载文件或程序集“System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”错误原因是因为PublicKeyToken的值和系统的PublicKeyToken

修改成一致:

<add assembly=”System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35″/>
<add assembly=”System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35″/>
<add assembly=”System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35″/>

[转载]文件上传控件第二波 - tebato - 博客园

mikel阅读(1217)

[转载]文件上传控件第二波 – tebato – 博客园.

上次分享了一款文件上传控件(网址:http://www.cnblogs.com/ushou/archive/2013/01/17/2865332.html),功能也比较多,但总觉得不够完美,经过近几天的发酵,酝酿,终于生产啦,吼吼~~~

这次的上传控件加入新的元素,比如附件列表展示、排序拖动、批量更新等。

俗话说,独乐乐不如众乐乐,现将关键代码分享。

一,首先在MVC中新建分部视图。

<link href="@Url.Content("~/Content/Uploadify/uploadify.css")" rel="stylesheet" type="text/css" />
<script type="text/JavaScript" src="@Url.Content("~/Content/Uploadify/swfobject.js")"></script>
<script type="text/JavaScript" src="@Url.Content("~/Content/Uploadify/JQuery.uploadify.v2.1.4.min.js")"></script>
<script src="@Url.Content("~/Content/zDialog/zDialog.js")" type="text/JavaScript"></script>
<script src="@Url.Content("~/Content/zDialog/zDrag.js")" type="text/javascript"></script>
<script type="text/javascript">
    $(document).ready(function () {
        $("#uploadify").uploadify({
            'uploader': '/Content/Uploadify/uploadify.swf',
            'script': '/Ashx/UploadHandler.ashx',
            'cancelImg': '/Content/Uploadify/cancel.png',
            'folder': '/UploadFile',
            'queueID': 'fileQueue',
            'multi': true,
            'auto': true,
            'fileExt': '*.jpg;*.gif;*.png',
            'fileDesc': 'Image Files (.JPG, .GIF, .PNG)',
            'queueID': 'custom-demo',
            'queueSizeLimit': 9999,
            'simUploadLimit': 9999,
            'buttonText': '选择文件',
            'removeCompleted': true,
            'onSelectOnce': function (event, data) {
            },
            'onComplete': function (event, queueId, fileObj, response, data) {                  
                AddFiles(response.split('|')[1], response.split('|')[2]);
            },
            'onAllComplete': function (event, data) {
            }
        });
    });
</script>

二:创建两个ashx文件,两个足矣,本来还想压缩到一个的,后来想想还是算了。

这两个ashx,分别拥有以下功能。

1,对数据库中的附件增、删、改、查。

关键代码如下:

public void ProcessRequest(HttpContext context)
{
    context.Response.ContentType = "text/html";
    string action = RequestExtension.GetQueryString<String>("action", "");
    if (action == "")
        return;
    MethodInfo methodInfo = this.GetType().GetMethod(action);
    if (methodInfo != null)
    {
        context.Response.Clear();
        context.Response.Write(methodInfo.Invoke(this, null));
        context.Response.End();
    }
}

这里action是传入函数名称,然后通过反射调用执行。

用法也是相当简捷:

如下示例:

修改:

$.post("/Ashx/Attachment.ashx?action=Modify", { fileID: fileID, fileName: fileName, fileDesc: fileDesc }, function (txt) {
    if (txt == "OK") {
        diag.close();
    }
    else {
        Dialog.alert(txt);
    }
}, "text");

删除:

//发送请求到服务器删除文件
var fileID = $(obj).parent().parent().attr("id");
$.post("/Ashx/Attachment.ashx?action=DelFile", { fileID: fileID }, function (txt) {
    if (txt == "OK") {
        Dialog.close();
        var p = $(obj).parent().parent();
        p.css('display', 'none');
    }
    else {
        Dialog.alert(txt);
    }
}, "text");

其他如新建、获取用法也如此,不再细述。

三:JS中操作生成元素、与数据库交互。

这里是新增附件、批量修改、删除附件的关键代码,中间还有页面元素拖动的功能。

function AddFilesUseTb(fileName, fileID, imgUrl) {
    var cloneTb = $('#tbTemplete').clone().attr('id', fileID);
    $('#uploadMsg').append(cloneTb.wrap('<div></div>').parent().html());
    $("#" + fileID).find("input:eq(0)").val(fileName);
    if (imgUrl != null) {
        $("#" + fileID).find("img:eq(0)").attr("src", imgUrl);
    }
    //文件上传完成后启用sortable
    $('.gbin1-list').sortable().bind('sortupdate', function () {
        
    });
            
    //文件上传完成后,自动更新序列号
    var fileList = $('#uploadMsg').find("table");
    var fileCount = $('#uploadMsg').find("table").length;
    $.post("/Ashx/Attachment.ashx?action=Modify", { fileID: fileID, fileName: fileName, fileDesc: "", IsMove: "N", sequenceNum: fileCount }, function (txt) {
        if (txt != "OK") {
            Dialog.alert("保存名称为:" + fileName + "的文件时出错,请重试");
        }
    }, "text");
}
function EditAllFiles(obj) {
    var fileList = $('#uploadMsg').find("table");
    var fileCount = $('#uploadMsg').find("table").length;
    for (var i = 0; i < fileCount; i++) {
        var fileID = $(fileList[i]).parent().attr("id");
        var fileName = $(fileList[i]).find("input:eq(0)").val();
        var fileDesc = $(fileList[i]).find("textarea:eq(0)").val();
        var IsMove = $(fileList[i]).find('input:checkbox:checked').val();
        if (IsMove == "on") {
            IsMove = "Y";
        }
        else {
            IsMove = "N";
        }
        $.post("/Ashx/Attachment.ashx?action=Modify", { fileID: fileID, fileName: fileName, fileDesc: fileDesc, IsMove: IsMove, sequenceNum: i+1 }, function (txt) {
            if (txt != "OK") {
                Dialog.alert("保存名称为:" + fileName + "的文件时出错,请重试");
            }
        }, "text");
    }
    $(obj).val("已保存");
};
function DelAllFiles(obj) {
    Dialog.confirm('警告:确定要删除附件?', function () {
        var fileList = $('#uploadMsg').find("table").each(function () {
            var fileID = $(this).parent().attr("id");
            var fileName = $(this).find("input:eq(0)").val();
            $.post("/Ashx/Attachment.ashx?action=DelFile", { fileID: fileID }, function (txt) {
                if (txt != "OK") {
                    Dialog.alert("删除名称为:" + fileName + "的文件时出错,请重试");
                }
            }, "text");
        });
    });
}
function DelFiles(obj) {
    Dialog.confirm('警告:确定要删除附件?', function () {
        //发送请求到服务器删除文件
        var tbSelect = $(obj).parent().parent().parent().parent().parent();
        var fileID = tbSelect.attr("id");
        $.post("/Ashx/Attachment.ashx?action=DelFile", { fileID: fileID }, function (txt) {
            if (txt == "OK") {
                Dialog.close();
                tbSelect.css('display', 'none');
            }
            else {
                Dialog.alert(txt);
            }
        }, "text");
    });
}

四:页如引用分部视图,只需一句话:@Html.Action(“Index”, “File”)

话说这MVC还真是牛掰,比ASP.NET简捷多了。

五:分享一下使用Dapper的分页代码。

public KeyValuePair<Pagination, IList<AttachmentModel>> AttachmentPagination(Pagination pagin, AttachmentModel condition)
{
    using (SQLConnection conn = DapperFactory.CrateOpenConnection())
    {
        String executeQuery = @"WITH pagintable AS(
                                SELECT ROW_NUMBER() OVER(ORDER BY CreateDate DESC )AS RowID, ID, FileID, TabName, TabID, FileName, FileDesc, FilePath, FileTypeID, FileSize, CreateDate, CreateMan, EditDate, EditMan, IsValid, NeedMoveToMoss, IsMoveToMoss, IsTemp,SequenceNum FROM Attachment
                                WHERE 1= 1)
                                SELECT * FROM pagintable where RowID between ((@CurrentPageIndex - 1)  * @PageSize) + 1  and (@CurrentPageIndex  * @PageSize)";
        String executeCount = "SELECT COUNT(*) AS CountNum FROM Attachment WHERE 1= 1";
        var mixCondition = new
        {
            CurrentPageIndex = pagin.CurrentPageIndex,
            PageSize = pagin.PageSize
        };
        List<AttachmentModel> listScore = conn.Query<AttachmentModel>(executeQuery, mixCondition).ToList();
        pagin.TotalItemCount = conn.Query<Int32>(executeCount, mixCondition).SingleOrDefault<Int32>();
        KeyValuePair<Pagination, IList<AttachmentModel>> result =
            new KeyValuePair<Pagination, IList<AttachmentModel>>(pagin, listScore);
        return result;
    }
}

这是使用CodeSmith自动生成的代码,秒秒钟搞定,并且相当灵活及高效。

上张图:

备注:这张图的两个附件顺序是可以拖动变更的,呵呵。

老样子,提供Demo网址,供用户试用及扒源码。

网址:www.qicheba.net

[转载]微信公众平台消息接口开发(1)启用接口 - txw1958 - 博客园

mikel阅读(1020)

[转载]微信公众平台消息接口开发(1)启用接口 – txw1958 – 博客园.

微信 平台 消息 接口 启用
作者:http://txw1958.cnblogs.com/

 

本系统教程以微信公众平台应用天气神(账号WeatherGod,支持国内近400个城市天气查询)为例,讲解微信接口开发过程。欢迎大家关注该账号,二维码见底部图。

使用前提条件:拥有一个公网上的HTTP服务器主机空间,具有创建目录、上传文件等权限。免费的也可以,但须有二级域名。想快速的申请一个免费稳定好用的,可以先使用新浪的SAE。但免费时间有限。

 

一、注册微信公平平台账号
地址:http://mp.weixin.qq.com/
过程略。

 

二、上传代码

以下代码是消息接口认证代码,将下列PHP代码保存为index.php(其中的mytoken改为你想要的的token名称),并上传到HTTP服务器指定的目录中,

复制代码
<?php define("TOKEN", "mytoken"); $wechatObj = new wechatCallbackapiTest(); $wechatObj->valid(); class wechatCallbackapiTest { public function valid() { $echoStr = $_GET["echostr"];        //随机字符串

        if($this->checkSignature()){ echo $echoStr; exit; } } private function checkSignature() { $signature = $_GET["signature"];    //微信加密签名
        $timestamp = $_GET["timestamp"];    //时间戳
        $nonce = $_GET["nonce"];            //随机数

        $token = TOKEN; $tmpArr = array($token, $timestamp, $nonce); sort($tmpArr);      //进行字典序排序 //sha1加密后与签名对比
        if( sha1(implode($tmpArr)) == $signature ){ return true; }else{ return false; } } } ?>
复制代码

或者直接下载微信的示例代码。地址 http://mp.weixin.qq.com/mpres/htmledition/res/wx_sample.zip

 

二、启用消息接口
进入微信公众平台,选择 设置关键词自动回复 ,选择启用 ,点击 公众平台消息接口 旁边的 编辑,进入接口配置界面:
按照要求如实填写下列选项。特别注意是URL是你上传index.php的路径,必须以http://开头,且为80端口。

填好后点击提交,这会有两种结果
1. 服务器没有响应Token验证,这样回头检查一下各项配置是否正确。

2. 提交成功

恭喜你,配置成功了。

 

 

关注天气神(账号WeatherGod)方法:

1. 依次进入以下路径:朋友们—>添加朋友—>搜号码,输入WeatherGod,不区分大小写,点击查找,然后点击关注

2. 扫描二维码:

 

[转载]ASP.NET MVC中Autofac实现的自动注入模式 - Nic Pei - 博客园

mikel阅读(1042)

转载ASP.NET MVC中Autofac实现的自动注入模式 – Nic Pei – 博客园.

熟悉IoC容器的都知道,在开发过程中,最郁闷的莫过于当你新增一个Service时,你需要对该Service进行注册,有的是使用代码注入,有的是XML配置注入,不管是哪种类型的注入,经常会出现开发人员忘记注入的情况,

如果你的页面是直接发送请求的,那么会得到类似于如下页面的错误:

image  <- _<-

 

如果该服务是用于AJAX请求实用的,那么你就悲剧了,因为页面只是没反应,只有查看错误日志了。

 

于是我试着去想办法去避免每次的服务都需要注入,而是系统自动注入。

image

 

红色线条框住的地方就是自动注入的代码实现。很高兴Autofac提供一个RegisterAssemblyTypes方法。它回去扫描所有的dll并把每个类注册为它所实现的接口。。。。

既然能够自动注入,那么接口和类的定义一定要有一定的规律。 从上面的代码可以看到baseType这个变量,它是IDependency接口的类型。

IDependency接口如下:

image

 

其他任何的接口都需要继承这个接口,例如我们定义一个接口IModelCar:

image

 

IModelCar的实现类:

 

image

 

自动注入原理说明:

 

 

 

首先我们去找到所有Dll,再去找到实现了IDependency接口的类,然后使用RegisterAssemblyTypes进行注入。

 

在Controller中调用试试:

image

 

可以看到_carmodel解析后为ModelCar的实例。。 微笑

 

Demo下载: https://github.com/nicholaspei/MvcApplication5

[转载]WEB站点性能优化实践(加载速度提升2s) - 大CC - 博客园

mikel阅读(1128)

[转载]WEB站点性能优化实践(加载速度提升2s) – 大CC – 博客园.

 进行优化前,关键是剖析当前的web性能,找到性能瓶颈,从而确定最需改进的地方;如果精力有限,首先将精力放在能明显提升性能的改进点上;

高性能网站建设指南》提出了一个性能黄金法则:

只有10%-20%的最终用户响应时间花在了下载HTML文档上;其余的80%-90%的时间花在了下载页面中的所有组件上。

由于本文将实施一个完整的优化流程,所以,我们还是从后台开始;

 

案例说明:

优化之前的网站规模:

2个js、一个页头、一个页脚;3个css;

类型:博客类站点;后台逻辑简单;首页不到10个SQL查询;

首页html文档52kb;

 

第一步:后台优化,启用页面缓存;

实验站点首页后台逻辑并不复杂,不超 过10个SQL查询,通过查看时间线,本站在获取HTML文档时,花费的时间不到总响应时间的20%,优化之前没有使用缓存,所有的数据都是从数据库读 取,这里,我们使用静态页面缓存,将首页整个页面完全的存放在缓存中(关于YII静态页面缓存的使用,参考这里);

通过查看html文档的生成时间来检测优化效果;

首字节时间为376ms;html生成的时间大大缩短,后台时间减少了一倍。

优化前:

wps_clip_image-20655

优化后:

wps_clip_image-4529

 

第二步,DNS域名解析加速:

DNS解析是用户访问站点的第一步,在此之前,你的网站无法做任何事情;

站点的DNS解析时间不应该超过500ms,如果站点原始DNS解析时间过长,就该考虑考虑使用第三方解析加速服务;

实验站点的原始DNS解析较慢,平均耗时1017ms,算是非常长的;对于DNS加速,可以使用DNS域名解析加速服务,本站点采用的国内的一款免费DNS加速服务DNSPOD,效果还不错,使用后平均耗时降到370ms;

加速前测试:

wps_clip_image-14761

使用DNS域名解析服务之后的测试:

wps_clip_image-16186

 

第三步:使用CDN加速;

采用第三方CDN加速,时间缩短到2.1s;从下图中看到主要的耗时在于并行下载的个数有些低,如果能够提升并行下载量的个数,那么整体加载时间就会降低;

注:个人建议,启用CDN最好放在最后一步,等将站点本身的优化都做完了之后,再启用CDN可以明显的看到优化效果。(开启CDN后,由于有CDN缓存的原因,观测站点的本身的优化就不是很方便了);

wps_clip_image-15052

 

第四步,采用多台服务器提高并行加载量:

原理:一个浏览器对与同一域名的并行下载的个数默认是2个, HTTP.1.0中规定的是4个。这样,我们可以使用不同的域名来提升下载的速度;

观察上图中的下载数量,第一次并行下载的个数是4个,初始认为是浏览器对于同一个域名来源的下载所限导致;于是考虑将部分静态文件分别放在不同的服务器上;通过把css和js放在不同服务器上;结果并不理想,发现并未提高速度。

想到在哪曾看到过,浏览器必须得把放在页头的css和js下载完成了之后才会开始下载其它的静态组件;

关于并行下载这点上,后续将继续实验是否还有优化的空间。

wps_clip_image-21817

 

第五步,合并脚本和样式表;

    本站首页使用了2个js和3个css。如果采用朴素复制的方式,将js和css都分别整合到一个文件中,不但操作麻烦,而且不方便后期的管理。网络上有不少合并的工具,本站采用了CSS和JS合并优化工具-minify(下载地址:http://code.google.com/p/minify/)。如果使用的YII框架,更有YII整合版(minscript Extension),简单几步的配置,就自动将页面所有的js和css文件合并;

关于minscript Extension的使用,请参考:https://bitbucket.org/TeamTPG/minscript/wiki/Usage

 

第六步,压缩css/js/html/xml;

不同的web服务器设置方式有所差别,本站使用的Linux/apache,

在web根目录下的.htaccess文件中添加以下代码即可:

#set compress

<ifmodule mod_deflate.c>

AddOutputFilter DEFLATE html xml php js css

</ifmodule>

通过firefox工具可看到,压缩前,html文档的大小是25KB;合并后的js大小为138KB;

wps_clip_image-2227

压缩后,html文档大小为6.2KB。js大小为39.8KB;减少2/3的传输时间;

wps_clip_image-10096

 

第六步,最大化的减少HTTP请求;

添加Expires头, 启用静态内容缓存,将jpg、gif等文件缓存;

方法也是在.htaccess中添加:

# Image and Flash content Caching for One Month

<FilesMatch “.(flv|gif|jpg|jpeg|png|ico|swf)$”>

Header set Cache-Control “max-age=2592360″

</FilesMatch>

 

结论

查看最终的测试结果,整体实现了较大 的性能提升,最终页面展现时间为1.62s(测试使用的是一个第三方web测速工具,所有测试结果是在第三方本地无缓存的条件下进行)。仔细观察本站最后 几个加载项:有一个第三方网站的广告(加载广告的时刻,页面已经全部呈现,对用户体验影响不大),以及cnzz的统计数据。这样看来,在第12项加载完 后,整个页面就完整的呈现在用户面前,优化最终结果是1.1s,较优化前加载速度提升2s;由于物理条件(虚拟机、国外站点)所限,本次优化就到此为止 (后续将在并行下载上做做文章,看是否有进一步提升空间)。

wps_clip_image-7016

 

本次优化主要使用的是前端优化,其中大部分规则来自于这本书的指导《高性能网站建设指南》;如果你的web前端部分还没有充分优化,强烈建议读读这本书;

这是一本你只需画上三小时就能看完,但收获价值远远大于付出的一本书。

image

附上本书的目录:

绪言A:前端性能的重要性

第1章:规则1——减少HTTP请求

第2章:规则2——使用内容发布网络

第3章:规则3——添加Expires头

第4章:规则4——压缩组件

第5章:规则5——将样式表放在顶部

第6章:规则6——将脚本放在底部

第7章:规则7——避免CSS表达式

第8章:规则8——使用外部JavaScript和CSS

第9章:规则9——减少DNS查找

第10章:规则10——精简JavaScript

第11章:规则11——避免重定向

第12章:规则12——移除重复脚本

第13章:规则13——配置ETag

第14章:规则14——使AjaX可缓存

第15章:析构十大网站

页面大小、响应时间、YSlow等级

如何进行测试