【知识碎片】Net项目经验积累

后台传JSON到js报错

MVC控制器传json到前端JS"变为" 导致JS报错

重点是一定要在@ViewBag.typeJson两边加双引号,并且后台用

编码前台解码

ViewBag.typeJson=System.Web.HttpUtility.UrlEncode(JsonConvert.SerializeObject(info));
var data =eval('(' + decodeURIComponent( "@ViewBag.typeJson") + ')'); 

响应报文 隐藏服务器信息

X-Powered-By:ASP.NET  这个需要在IIS中移除

选择你需要修改的站点并双击HTTP响应头部分

所有的自定义HTTP头全在这里了,删除相应的头仅需要点击右边的”Remove”

在代码中实现的

HttpContext.Response.Headers.Remove("X-AspNet-Version");
HttpContext.Response.Headers.Remove("X-AspNetMvc-Version");

HttpContext.Response.Headers.Set("Server", "Nginx-57blog-VIP");

在webconfig中实现的

MVC的版本信息

<httpRuntime enableVersionHeader="false" />

在wencongig中加这个就可以了

URL重写方案总结

方法一:使用现成的插件,比如:ISAPI_Rewrite、IIS Rewrite、Apache HTTP服务器的mod_rewrite等,它们都是基于正则表达式解析器开发的重写引擎。它们的使用方法查看它们自带的帮助即可。
方法二:自己写的代码实现动态网页静态化,方法也有好几种:
1、创建FSO对象,利用此对象将所需的内容动态创建到文件中生成HTML页面;
2、利用模板技术,将模板中特殊代码的值替换为从表单或是数据库字段中接受过来的值 生成HTML文件
3、使用Server.Transfer转换技术,
方法三:使用HttpWebRequest请求客户端的方式,获取返回资源,生成静态页面。一般这样只需要获取网页内容即可,其它资源可放置在服务器上,自动加载。(注:此方法缺点明显,需要大量更改匹配URL,建议慎用)
方法四:在asp中有IhttpModule接口。Ihttpmodule可以简单理解为一个可以在执行像.aspx,或者mvc中control/action前,添加我们自定义的操作的东西。
我们只需要编写这么一个HttpModule就可以了,当用户第一次请求asp处理时,我们可以在ihttpmodule中拦截到这个请求,然后获取到这次请求应该返回的html代码,然后我们返回这些html给用户,并保存刚才我们获取到的html到文件内,当用户下次请求时,我们只需要直接返回我们已经保存的html文件即可。

数据库设计

1、表的设计合理(三范式)

2、添加合适的索引

3、分表技术(水平分割、垂直分割

4、定时清除垃圾数据、定时进行碎片整理

5、多用存储过程、触发器

6、读写分离

良好的数据库: 介绍存储空间 保证数据完整性 糟糕的:数据冗(rong)余 不完整数据

分库解决方案 

自己设定一定的规则 比如hash 或者取膜

比如ID  单数设定一个连接字符串  双数设定一个连接字符串

或者根据ID的位数  或者根据拼音  汉字笔画字符长度等

当ID时单数的时候  存的时候存到1库  取得时候又计算ID等于单数的时候去1库取

如果是获取列表页没有问题  用户ID为3的文章文章都存在库1上获取的时候 不需要获取所有用户的文章

网站架构演变:单主机-缓存服务器-页面缓存-服务器集群-数据库分库--分布式数据库

负载均衡

硬件Netscaler F5 Radware Array

软件 LVS nginx apache tengine(淘宝的,提交给nginx nginx不接受,就自己写了)

LVS:http://www.cnblogs.com/edisonchou/p/4281978.html 

搭建主机 :
需要安装一个软件 keepalived
故障移除 把服务器关掉一个,在转发的时候就不转发到这台机器
故障恢复 启动后,又开始转发
主机挂了 备机接管主机的工作

通过心跳检查检测主机是否挂了

nginx  反向代理服务器  异步非阻塞式  官方高并发5W   实际生产2-3W 

管道事件

第一个事件  beginrequrest   第七个第八个之间 根据文件扩展名判断是一般处理程序还是页面程序,如果是ashx就创建httphandler实例  如果是aspx就创建Page对象(每次请求都会有一个IhttpHandler对象去处理当前请求)

在第七个事件之前如果指定了handler  在第七第八个事件之间就创建指定的handler

1-7之间如果指定当前请求处理程序,7-8就不会创建

11-12 执行刚刚创建的IhhttpHandler.processrequest() 如果是page 执行声明周期

Page类回调技术 单页模式

在前台页面直接写一个 protected void Page_Load(obeject obj,Event e)  就不需要后台页面了   可以直接删除了,要放在 <script runat="server"></script> 内

这里面也可以写其他函数  不过还是写在后台效率高,直接编译dl了,aspx是动态编译效率低

<%@ Page Language="C#" ContentType="text/html" ResponseEncoding="gb2312" %>
<%@ Implements Interface="System.Web.UI.ICallbackEventHandler" %>
<%@ Import Namespace="System.Text" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>用户注册</title>
<script language="javascript">
//客户端执行的方法
//下面的方法是接收并处理服务器方法执行的返回结果
function Success(args, context)
{
    message.innerText  = args;
}
//下面的方式是当接收服务器方法处理的结果发生异常时调用的方法
function Error(args, context)
{
    message.innerText  = '发生了异常';
}
</script>
<script language="c#" runat="server">
string result="";
// 定义在服务器端运行的回调方法.
public void RaiseCallbackEvent(String eventArgument)
{
 if(eventArgument.ToLower().IndexOf("admin")!=-1)
 {
  result=eventArgument+"不能作为用户名注册。";
 }
 else
 {
  result=eventArgument+"可以注册。";
 }
 //throw new Exception();
}
//定义返回回调方法执行结果的方法
public string GetCallbackResult()
{
 return result;
}
//服务器上执行的方法
public void Page_Load(Object sender,EventArgs e)
{
 // 获取当前页的ClientScriptManager的引用
    ClientScriptManager csm = Page.ClientScript;
 // 获取回调引用。会在客户端生成WebForm_DoCallback方法,调用它来达到异步调用。这个方式是微软写的方法,会被发送到客户端
 //注意这里的"Success"和"Error"两个字符串分别客户端代码中定义的两个javascript函数
 //下面的方法最后一个参数的意义:true表示执行异步回调,false表示执行同步回调
 String reference = csm.GetCallbackEventReference(this, "args","Success","","Error",false);
 String callbackScript = "function CallServerMethod(args, context) {/n" + 
  reference + ";/n }";
 // 向当前页面注册javascript脚本代码
 csm.RegisterClientScriptBlock(this.GetType(), "CallServerMethod", 
  callbackScript, true);
}
</script>
</head>
<body>
<form id="form1" runat="server">
<table border="1" cellpadding="0" cellspacing="0" width="400px">
<tr>
<td width="100px">用户名</td><td><input type="text" size="10" maxlength="20" id="txtUserName" onblur="CallServerMethod(txtUserName.value,null)" /><span id="message"></span></td>
</tr>
<tr>
<td>密码</td><td><input type="password" size="10" maxlength="20" id="txtPwd" /></td>
</tr>
</table>
</form>
</body>
</html>
View Code

通过一个aspx文件直接获取服务器web.config文件

<%@ Page Language="C#" ContentType="text/html" ResponseEncoding="gb2312" %>

<%@ Import Namespace="System.Text" %>
<%@ Import Namespace="System.IO"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>用户注册</title>
<script language="javascript">

</script>
<script language="c#" runat="server">
string result="";

//服务器上执行的方法
public void Page_Load(Object sender,EventArgs e)
{
            using (FileStream fs = new FileStream(Server.MapPath("/")+"Web.config", FileMode.Open, FileAccess.Read))
            {
                byte[] buffer = new byte[fs.Length];
                fs.Read(buffer, 0, buffer.Length);
                string msg = System.Text.Encoding.UTF8.GetString(buffer);
                //Response.Write(msg);

                string timeNow = DateTime.Now.ToString();
                Response.Clear();
                Response.Buffer = false;
                Response.ContentType = "application/octet-stream";
                Response.AppendHeader("content-disposition", "attachment;filename=" + "Web" + ".config;");

                Response.Write(msg);
                Response.Flush();
                Response.End();
            }
}
</script>
</head>
<body>

</body>
</html>
View Code

系统Host

host 地址C:WindowsSystem32driversetc  

刷新缓存命令:

cmd   ipconfig /flushdns

多个域名绑定一个IP  

127.0.0.1       localhost www.57blog.com xiaoshi57.57blog.com #多个用空格隔开即可

QQ登录

张善友博客 http://www.cnblogs.com/shanyou/archive/2012/02/05/2338797.html

NVelocity 视图模板引擎

NVelocity 视图模板引擎 如 razor vtemplate

CDN加速

全国各地布服务器  把资源放到每个服务器上,就叫CDN加速

 API认证原理

api认证  想到就记下来了

用一个md5、hash或者其他的加密算法

这个秘钥由以下部分组成:

tiame: 时间(动态的就行可以不是时间(guid))

key: 随意写一个盐就可以,这个盐不能传输,客户端和服务端之后即可

其他的就无所谓了

然后加一起生成MD5,把这个MD5传给服务端  服务端把客户端传来的时间加上盐然后计算出MD5和你传来的MD5值对比,即可

订单存储过程

存储过程比放在程序里的SQL速度快

存储过程只编译一次  程序里的每次请求都需要编译

 安全 不会有SQL注入

缺点 可移植性差

互联网项目一般不用存储过程  

create proc createOrder
@address nvarchar(255),--收货人地址
@orderId nvarchar(50),--订单号
@userId int,--用户编号
@totalMoney money output --总金额
as
begin
  declare @error int
  set @error=0
  begin transaction
   ---计算总金额
  select @totalMoney=sum([Count]*UnitPrice)from Cart inner join Books on Cart.BookId=Books.Id where Cart.UserId=@userId
   set @error=@@error+@error
  --向订单主表中插入数据。
  insert into dbo.Orders(OrderId, OrderDate, UserId, TotalPrice, PostAddress, state) values(@orderId,getdate(),@userId,@totalMoney,@address,0)
set @error=@@error+@error
 --行订单明细表中插入数据
  insert into dbo.OrderBook(OrderID, BookID, Quantity, UnitPrice) select @orderId,Cart.BookId,Cart.Count,Books.UnitPrice from Cart inner join Books on Cart.BookId=Books.Id where Cart.UserId=@userId
  set @error=@@error+@error
--删除购物车表中的数据
  delete from Cart where UserId=@userId
  set @error=@@error+@error
  if @error>0
    begin
        rollback transaction--回滚
    end
  else
     begin
        commit transaction--提交
     end 
end
View Code

正则过滤禁用词

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace BookShop.BLL
{
    public class Articel_WordsManager
    {
        DAL.Articel_WordsService dal = new DAL.Articel_WordsService();
        public bool Insert(Model.Articel_Words model)
        {
            return dal.Insert(model)>0;
        }
        /// <summary>
        /// 判断用户的评论中是否有禁用词
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        public bool CheckForbid(string msg)
        {
            List<string> list = dal.GetForbidWord();//获取所有的禁用词 放入缓存中。
            string regex = string.Join("|",list.ToArray());//aa|bb|cc|
            return Regex.IsMatch(msg, regex);
            //foreach (string word in list)
            //{
            //    msg.Contains(word);
            //    break;
            //}

        }
        /// <summary>
        /// 审查词过滤
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        public bool CheckMod(string msg)
        {

            List<string> list = dal.GetModWord();//获取所有的审查词,放入缓存中。
            string regex = string.Join("|", list.ToArray());//aa|bb|cc|
            regex = regex.Replace(@"", @"\").Replace("{2}",@".{0,2}");
            return Regex.IsMatch(msg, regex);
        }
        /// <summary>
        /// 替换词过滤
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        public string CheckReplace(string msg)
        {
            List<Model.Articel_Words> list = dal.GetReplaceWord();//放入缓存中。
            foreach (Model.Articel_Words model in list)
            {
                msg = msg.Replace(model.WordPattern, model.ReplaceWord);
            }
            return msg;
        }
    }
}
View Code

生成静态页面

/// <summary>
        /// 将商品的信息生成静态页面
        /// </summary>
        public void CreateHtmlPage(int id)
        {
            Model.Book model=dal.GetModel(id);
            //获取模板文件
            string template = HttpContext.Current.Request.MapPath("/Template/BookTemplate.html");
            string fileContent = File.ReadAllText(template);
            fileContent = fileContent.Replace("$title", model.Title).Replace("$author", model.Author).Replace("$unitprice",model.UnitPrice.ToString("0.00")).Replace("$isbn",model.ISBN).Replace("$content",model.ContentDescription).Replace("$bookId",model.Id.ToString());
            string dir = "/HtmlPage/" + model.PublishDate.Year + "/" + model.PublishDate.Month + "/" + model.PublishDate.Day + "/";
            Directory.CreateDirectory(Path.GetDirectoryName(HttpContext.Current.Request.MapPath(dir)));
            string fullDir = dir + model.Id + ".html";
            File.WriteAllText(HttpContext.Current.Request.MapPath(fullDir), fileContent, System.Text.Encoding.UTF8);

        }
View Code
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>

    <title>$title</title>
    <meta content="北京市新华书店王府井书店,致力于提供专业化购书服务.网上购书选择新华书店王府井书店(网上书店),购书放心有保障.王府井书店电话:010-65132842.010-65252592" name="description"/>
<meta content="王府井书店 新华书店 网上书店 网上购书 北京图书大厦" name="keywords"/>

    <link href="/Css/tableStyle.css" rel="stylesheet" /><!--在模板文件中引用外部文件时一定要使用绝对路径-->
    <link href="/Css/index.css" rel="stylesheet" />
    <script src="/js/jquery-1.7.1.js"></script>
    <script src="/ckeditor/ckeditor.js"></script>
    <style type="text/css">
      
        .itcast_comments{ width:620px;color: #333;font: normal 12px/24px Helvetica, Tahoma, Arial, sans-serif; font-size:14px;}
           .reply_btn{ font-size:14px; background:#cc0000; padding:8px 15px; border:none; color:#fff; cursor: pointer; font:"Microsoft YaHei"; font-weight:bold;}
           .reply_box{border:1px solid #CCC; font-size:14px;}
    </style>
    <script type="text/javascript">
        $(function () {
            $("#btnAdd").click(function () {
                addComment();
            });
            loadComment();//加载评论
            loadUBBCode();//加载UBB编辑器
        });
        //加载UBB编辑器
        function loadUBBCode() {
            CKEDITOR.replace('txtContent',
    {
        extraPlugins: 'bbcode',
        removePlugins: 'bidi,button,dialogadvtab,div,filebrowser,flash,format,forms,horizontalrule,iframe,indent,justify,liststyle,pagebreak,showborders,stylescombo,table,tabletools,templates',
        toolbar:
        [
            ['Source', '-', 'Save', 'NewPage', '-', 'Undo', 'Redo'],
            ['Find', 'Replace', '-', 'SelectAll', 'RemoveFormat'],
            ['Link', 'Unlink', 'Image'],
            '/',
            ['FontSize', 'Bold', 'Italic', 'Underline'],
            ['NumberedList', 'BulletedList', '-', 'Blockquote'],
            ['TextColor', '-', 'Smiley', 'SpecialChar', '-', 'Maximize']
        ],
        smiley_images:
        [
            'regular_smile.gif', 'sad_smile.gif', 'wink_smile.gif', 'teeth_smile.gif', 'tounge_smile.gif',
            'embaressed_smile.gif', 'omg_smile.gif', 'whatchutalkingabout_smile.gif', 'angel_smile.gif', 'shades_smile.gif',
            'cry_smile.gif', 'kiss.gif'
        ],
        smiley_descriptions:
        [
            'smiley', 'sad', 'wink', 'laugh', 'cheeky', 'blush', 'surprise',
            'indecision', 'angel', 'cool', 'crying', 'kiss'
        ]
    });
        }

       //加载评论
        function loadComment() {
            $.post("/ashx/BookComment.ashx", { "action": "load", "bookId": $bookId }, function (data) {
                var serverData = $.parseJSON(data);
                var serverDataLength = serverData.length;
                for (var i = 0; i < serverDataLength; i++) {
                    $("<li>" + serverData[i].CreateDateTime + ":" + serverData[i].Msg + "</li>").appendTo("#commentList");
                }
            });
        }
        //添加评论
        function addComment() {
            //var msg = $("#txtContent").val();
            var oEditor = CKEDITOR.instances.txtContent;//找到UBB编辑器
            var msg = oEditor.getData();//获取编辑器内容
            if (msg != "") {
                $.post("/ashx/BookComment.ashx", { "action": "add", "msg": msg, "bookId": $bookId }, function (data) {
                    var serverData = data.split(':');
                    if (serverData[0] == "ok") {
                        // $("#txtContent").val("");
                        oEditor.setData("");
                        $("#txtContent").focus();
                        loadComment();
                        $("#txtMsg").text(serverData[1]);
                    } else {
                        $("#txtMsg").text(serverData[1]);
                    }

                });
            } else {
                $("#txtMsg").text("评论内容不能为空!!");
                $("#txtContent").focus();
            }
        }
    </script>
</head>
<body>
    <center>
    <div class="top">
    <div class="m_c" style=" 736px; height: 27px">
    <span class="l">
      <a href="http://www.beifabook.com" target="_blank">北发图书网主网站</a> |&nbsp;
      <a href="http://www.bjbb.com" target="_blank">北京图书大厦</a>&nbsp; |
      <a href="../default.aspx" target="_blank"><font color="#00A0E9">王府井书店</font></a>&nbsp;|
      <a href="http://www.zgcbb.com/" target="_blank">中关村图书大厦</a>&nbsp; |
      <a href="http://www.yycbook.com/" target="_blank">亚运村图书大厦</a>&nbsp; |
      <a href="http://www.hs-book.com" target="_blank">花市书店</a>&nbsp; |
      <a href="/OrderInfo.aspx" >我的订单</a></span></div></div>


    <div style="WIDTH: 750px; text-align: left;"><img src="/images/集团网站1.jpg" width="780" height="93" /><br />
&nbsp;&nbsp;&nbsp;&nbsp;         </div>
        </center>

    <table>
        <tr><td>书名</td><td>$title</td></tr>
         <tr><td>作者</td><td>$author</td></tr>
         <tr><td>单价</td><td>$unitprice</td></tr>
         <tr><td>封面</td><td><img src="/Images/BookCovers/$isbn.jpg" /></td></tr>
        <tr><td>简介</td><td>$content</td></tr>
    </table>
    <hr />
    <ul id="commentList" class="itcast_comments">

    </ul>
    <textarea id="txtContent" rows="20" cols="100" class="reply_box" placeholder="有什么感想?来说说!!"></textarea><br />
    <input type="button" value="发布评论" id="btnAdd" class="reply_btn" /><span id="txtMsg" style="font-size:14px;color:red"></span>
    <div id="footer">
  <table border="0" width="100%" class="categories1">
    <tr>
      <td align="center"> 
        <ul>
            <li><a href='#'>关于我们王府井书店</li>
          <li><a href="#">书店营业时间:9:30-21:00 </a> </li>
          <li> <a href="#"; target=_blank; ><img src="/images/logo123x40.jpg" width="123" height="40" border="0"></a> <a href="#"; target=_blank; ><img border="0" src="/Images/kaixin.jpg"></a> </li>
          <li>&nbsp;<span lang="zh-cn"><a title="京ICP备08001692号" href="http://www.miibeian.gov.cn">京ICP备08987373号</a></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </li>
        </ul></td>
    </tr>
  </table>
</div>


</body>
</html>
View Code

发送邮件 找回密码

/// <summary>
      /// 找回用户的密码
      /// </summary>
      /// <param name="userInfo"></param>
        public void FindUserPwd(Model.User userInfo)
        {
            BLL.SettingsManager bll = new SettingsManager();
            //系统产生一个新的密码,然后更新数据库,再将新的密码发送到用户的邮箱中。
            string newPwd = Guid.NewGuid().ToString().Substring(0,8);
            userInfo.LoginPwd = newPwd;//一定要将系统产生的新密码加密以后更新到数据库中,但是发送到用户邮箱中的密码必须是明文的。
            dal.Update(userInfo);
            MailMessage mailMsg = new MailMessage();//两个类,别混了,要引入System.Net这个Assembly
            mailMsg.From = new MailAddress(bll.GetValue("系统邮件地址"));//源邮件地址 
            mailMsg.To.Add(new MailAddress(userInfo.Mail));//目的邮件地址。可以有多个收件人
            mailMsg.Subject = "在商城网站中的新的账户";//发送邮件的标题 
            StringBuilder sb = new StringBuilder();
            sb.Append("用户名是:"+userInfo.LoginId);
            sb.Append("新密码是:"+newPwd);
            mailMsg.Body =sb.ToString();//发送邮件的内容 
            //mailMsg.IsBodyHtml = true;
            SmtpClient client = new SmtpClient(bll.GetValue("系统邮件SMTP"));//smtp.163.com,smtp.qq.com
            client.Credentials = new NetworkCredential(bll.GetValue("系统邮件用户名"), bll.GetValue("系统邮件密码"));
            client.Send(mailMsg);//注意:发送大量邮件时阻塞,所以可以将要发送的邮件先发送到队列中。



        }
View Code

.Net自带缓存helper

using System;
using System.Web;
using System.Collections;

public class CookiesHelper
{
    /**//// <summary>
    /// 获取数据缓存
    /// </summary>
    /// <param name="CacheKey"></param>
    public static object GetCache(string CacheKey)
    {
        System.Web.Caching.Cache objCache = HttpRuntime.Cache;
        return objCache[CacheKey];
    }

    /**//// <summary>
    /// 设置数据缓存
    /// </summary>
    public static void SetCache(string CacheKey, object objObject)
    {
        System.Web.Caching.Cache objCache = HttpRuntime.Cache;
        objCache.Insert(CacheKey, objObject);
    }

    /**//// <summary>
    /// 设置数据缓存
    /// </summary>
    public static void SetCache(string CacheKey, object objObject, TimeSpan Timeout)
    {
        System.Web.Caching.Cache objCache = HttpRuntime.Cache;
        objCache.Insert(CacheKey, objObject, null, DateTime.MaxValue, Timeout, System.Web.Caching.CacheItemPriority.NotRemovable, null);
    }

    /**//// <summary>
    /// 设置数据缓存
    /// </summary>
    public static void SetCache(string CacheKey, object objObject, DateTime absoluteExpiration, TimeSpan slidingExpiration)
    {
        System.Web.Caching.Cache objCache = HttpRuntime.Cache;
        objCache.Insert(CacheKey, objObject, null, absoluteExpiration, slidingExpiration);
    }

    /**//// <summary>
    /// 移除指定数据缓存
    /// </summary>
    public static void RemoveAllCache(string CacheKey)
    {
        System.Web.Caching.Cache _cache = HttpRuntime.Cache;
        _cache.Remove(CacheKey);
    }

    /**//// <summary>
    /// 移除全部缓存
    /// </summary>
    public static void RemoveAllCache()
    {
        System.Web.Caching.Cache _cache = HttpRuntime.Cache;
        IDictionaryEnumerator CacheEnum = _cache.GetEnumerator();
        while (CacheEnum.MoveNext())
        {
            _cache.Remove(CacheEnum.Key.ToString());
        }
    }
}
View Code

Url重写 

把带参数的改写成不带参数的,BookDetail.aspx?id=52 -->BookDetai_52.aspx

有利于SEO优化

(不推荐这样在管道写,推荐使用IIS插件 url rewrite)

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

namespace BookShop.Web
{
    public class Global : System.Web.HttpApplication
    {

        protected void Application_Start(object sender, EventArgs e)
        {

        }

        protected void Session_Start(object sender, EventArgs e)
        {

        }
        /// <summary>
        /// 请求管道中第一个事件触发以后调用的方法,完成URL重写。
        /// URL重写。
       ///带参数的URL地址进行改写。改写成不带参数的。
        //BookDetail.aspx?id=2;   BookDetail_2.aspx

        //为什么将带参数的URL地址改成不带参数的?URL重写的目的就是SEO。

        //SEO.

        //怎样进行URL重写?

        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Application_BeginRequest(object sender, EventArgs e)
        {
            string url = Request.AppRelativeCurrentExecutionFilePath;//~/BookDetail_4976.aspx
            Match match=Regex.Match(url, @"~/BookDetail_(d+).aspx");
            if (match.Success)
            {
                Context.RewritePath("/BookDetail.aspx?id="+match.Groups[1].Value);
            }

            //Match match = Regex.Match(url, @"~/BookDetail_(d+).aspx");
            //if (match.Success)
            //{
            //    Context.RewritePath("/BookDetail.aspx?id=" + match.Groups[1].Value);
            //}




        }

        protected void Application_AuthenticateRequest(object sender, EventArgs e)
        {

        }

        protected void Application_Error(object sender, EventArgs e)
        {

        }

        protected void Session_End(object sender, EventArgs e)
        {

        }

        protected void Application_End(object sender, EventArgs e)
        {

        }
    }
}
View Code

SWFUpload 文件上传

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="CutPhoto.aspx.cs" Inherits="BookShop.Web.Member.CutPhoto" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    <link href="../Css/themes/ui-lightness/jquery-ui-1.8.2.custom.css" rel="stylesheet" />
       <script src="../js/jquery-1.7.1.js"></script>
    <script src="../js/jquery-ui-1.8.2.custom.min.js"></script>
    <script src="../SWFUpload/swfupload.js"></script>
    <script src="../SWFUpload/handlers.js"></script>
      <script type="text/javascript">
          var swfu;
          window.onload = function () {
              swfu = new SWFUpload({
                  // Backend Settings
                  upload_url: "/ashx/upload.ashx?action=upload",
                  post_params: {
                      "ASPSESSID": "<%=Session.SessionID %>"
                },

                // File Upload Settings
                file_size_limit: "2 MB",
                file_types: "*.jpg;*.gif",
                file_types_description: "JPG Images",
                file_upload_limit: 0,    // Zero means unlimited

                // Event Handler Settings - these functions as defined in Handlers.js
                //  The handlers are not part of SWFUpload but are part of my website and control how
                //  my website reacts to the SWFUpload events.
                swfupload_preload_handler: preLoad,
                swfupload_load_failed_handler: loadFailed,
                file_queue_error_handler: fileQueueError,
                file_dialog_complete_handler: fileDialogComplete,
                upload_progress_handler: uploadProgress,
                upload_error_handler: uploadError,
                upload_success_handler: showImage,
                upload_complete_handler: uploadComplete,

                // Button settings
                button_image_url: "/SWFUpload/images/XPButtonNoText_160x22.png",
                button_placeholder_id: "spanButtonPlaceholder",
                button_ 160,
                button_height: 22,
                button_text: '<span class="button">请选择上传图片<span class="buttonSmall">(2 MB Max)</span></span>',
                button_text_style: '.button { font-family: Helvetica, Arial, sans-serif; font-size: 14pt; } .buttonSmall { font-size: 10pt; }',
                button_text_top_padding: 1,
                button_text_left_padding: 5,

                // Flash Settings
                flash_url: "/SWFUpload/swfupload.swf",    // Relative to this file
                flash9_url: "/SWFUpload/swfupload_FP9.swf",    // Relative to this file

                custom_settings: {
                    upload_target: "divFileProgressContainer"
                },

                // Debug Settings
                debug: false
            });
        }
        //上传成功以后调用该方法
        function showImage(file, serverData) {
            // $("#showPhoto").attr("src", serverData);
            var data = serverData.split(':');
            //将上传成功的图片作为DIV的背景
            $("#hiddenImageUrl").val(data[0]);//将上传成功的图片路径存储到隐藏域中。
            $("#divContent").css("backgroundImage", "url('" + data[0] + "')").css("width",data[1]+"px").css("height",data[2]+"px");
        }

        $(function () {
            //让DIV可以移动与拖动大小
            $("#divCut").draggable({ containment: "#divContent", scroll: false }).resizable({
                containment: "#divContent"
            });
            $("#btnCut").click(function () {
                cutPhoto();
            });
        })
          //截取头像
        function cutPhoto() {
            //计算要截取的头像的范围。
            var y = $("#divCut").offset().top - $("#divContent").offset().top;//纵坐标
            var x = $("#divCut").offset().left - $("#divContent").offset().left;
            var width = $("#divCut").width();
            var heigth = $("#divCut").height();
            var pars = {
                "x": x,
                "y": y,
                "width": width,
                "height": heigth,
                "action": "cut",
                "imgSrc": $("#hiddenImageUrl").val()
                
            };
            $.post("/ashx/upload.ashx", pars, function (data) {
                $("#showPhoto").attr("src",data);
            });

        }

    </script>
</head>
<body>
    <form id="form1" runat="server">
   <div id="content">
        <div id="swfu_container" style="margin: 0px 10px;">
            <div>
                <span id="spanButtonPlaceholder"></span>
            </div>
            <div id="divFileProgressContainer" style="height: 75px;"></div>
            <div id="thumbnails"></div>
            <div id="divContent" style="300px; height:300px;">
                <div id="divCut" style="100px;height:100px; border:solid red 1px">
                </div>

            </div>
            <input type="button" value="截取图片" id="btnCut" />
            <input type="hidden" id="hiddenImageUrl" />
            <img id="showPhoto"></img>
        </div>
        </div>
    </form>
</body>
</html>
View Code
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Web;

namespace BookShop.Web.ashx
{
    /// <summary>
    /// upload 的摘要说明
    /// </summary>
    public class upload : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/plain";
            string action = context.Request["action"];
            if (action == "upload")//上传图片
            {
                ProcessFileUpload(context);
            }
            else if (action =="cut")//截取图片
            {
                ProcessCutPhoto(context);
            }
            else
            {
                context.Response.Write("参数错误!!");
            }
        }
        /// <summary>
        /// 文件上传
        /// </summary>
        /// <param name="context"></param>
        private void ProcessFileUpload(HttpContext context)
        {
            HttpPostedFile file = context.Request.Files["Filedata"];
            if (file != null)
            {
                string fileName = Path.GetFileName(file.FileName);
                string fileExt = Path.GetExtension(fileName);
                if (fileExt == ".jpg")
                {
                    string dir = "/ImageUpload/" + DateTime.Now.Year + "/" + DateTime.Now.Month + "/" + DateTime.Now.Day + "/";
                    if (!Directory.Exists(context.Request.MapPath(dir)))
                    {
                        Directory.CreateDirectory(context.Request.MapPath(dir));
                    }
                    string newfileName = Guid.NewGuid().ToString();
                    string fullDir = dir + newfileName + fileExt;
                    file.SaveAs(context.Request.MapPath(fullDir));
                    using (Image img = Image.FromFile(context.Request.MapPath(fullDir)))
                    {
                        context.Response.Write(fullDir + ":" + img.Width + ":" + img.Height);
                    }

                    //file.SaveAs(context.Request.MapPath("/ImageUpload/"+fileName));
                    //context.Response.Write("/ImageUpload/" + fileName);
                }
            }
        }

        /// <summary>
        /// 图片的截取
        /// </summary>
        /// <param name="context"></param>
        private void ProcessCutPhoto(HttpContext context)
        {
            int x = Convert.ToInt32(context.Request["x"]);
            int y = Convert.ToInt32(context.Request["y"]);
            int width = Convert.ToInt32(context.Request["width"]);
            int height = Convert.ToInt32(context.Request["height"]);
            string imgSrc = context.Request["imgSrc"];//获取上传成功的图片的路径
            using (Bitmap map = new Bitmap(width, height))
            {
                using (Graphics g = Graphics.FromImage(map))
                {
                    using (Image img = Image.FromFile(context.Request.MapPath(imgSrc)))
                    {
                        //第一个参数:表示画哪张图片.
                        //二:画多么大。
                        //三:画原图的哪块区域
                        g.DrawImage(img, new Rectangle(0, 0, width, height), new Rectangle(x, y, width, height), GraphicsUnit.Pixel);
                        string newfileName = Guid.NewGuid().ToString();
                        string fullDir = "/ImageUpload/" + newfileName + ".jpg";
                        map.Save(context.Request.MapPath(fullDir),System.Drawing.Imaging.ImageFormat.Jpeg);
                        context.Response.Write(fullDir);

                    }
                   
                }
            }
        }

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

一边处理程序调用session

一般处理程序调用session 必须实现接口 IReadOnlySessionState

spring.net

1 ioc  控制反转  以前自己new 这个是交给容器new

2 di  依赖注入  在创建类实例的时候  可以给一些属性完成初始化复制  (spring.net  配置文件中ref和value 等同,只是他是指的对象)

3 aop 面向切面编程 权限校验 日志处理

Unity  微软推出的实现 ioc di

Memcache

 socket通信,网站服务器上安装客户端端,其他的缓存服务器 称为服务端,通过它的算法,取其中一个存取

没有主从  存取都是在memcache客户端

 惰性删除:它并没有提供监控数据过期的机制,而是惰性的,当查询到某个key数据时,如果过期那么直接抛弃,如果存满了,把一些不经常访问的删除掉

http://www.cnblogs.com/caokai520/p/4390646.html

实例代码 建议修改一下 把下面的两个结合一下

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Memcached.ClientLibrary;


namespace Hep.Memcached.Uitils
{
    public class MemberHelper
    {
        static SockIOPool _pool;

        #region 创建Memcache服务
        /// <summary>
        /// 创建Memcache服务
        /// </summary>
        /// <param name="serverlist">IP端口列表</param>
        /// <param name="poolName">Socket连接池名称</param>
        /// <returns>Memcache客户端代理类</returns>
        private static MemcachedClient CreateServer(ArrayList serverlist, string poolName)
        {
            if (_pool != null)
            {
            }
            else
            {
                ////初始化memcache服务器池
                _pool = SockIOPool.GetInstance(poolName);
                //设置Memcache池连接点服务器端。
                _pool.SetServers(serverlist);

                ////其他参数根据需要进行配置 

                //各服务器之间负载均衡的设置
                _pool.SetWeights(new int[] { 1 });
                //socket pool设置
                _pool.InitConnections = 5; //初始化时创建的连接数
                _pool.MinConnections = 5; //最小连接数
                _pool.MaxConnections = 250; //最大连接数
                //连接的最大空闲时间,下面设置为6个小时(单位ms),超过这个设置时间,连接会被释放掉
                _pool.MaxIdle = 1000 * 60 * 60 * 6;
                //通讯的超时时间,下面设置为3秒(单位ms),.NET版本没有实现
                _pool.SocketTimeout = 1000 * 3;
                //socket连接的超时时间,下面设置表示连接不超时,即一直保持连接状态
                _pool.SocketConnectTimeout = 0;
                _pool.Nagle = false; //是否对TCP/IP通讯使用Nalgle算法,.NET版本没有实现
                //维护线程的间隔激活时间,下面设置为60秒(单位s),设置为0表示不启用维护线程
                _pool.MaintenanceSleep = 60;
                //socket单次任务的最大时间,超过这个时间socket会被强行中断掉(当前任务失败)
                _pool.MaxBusy = 1000 * 10;
                _pool.Initialize();

            }
            //创建了一个Memcache客户端的代理类。
            MemcachedClient mc = new MemcachedClient();
            mc.PoolName = poolName;
            mc.EnableCompression = false;//是否压缩 

            return mc;
        }
        #endregion

        #region 缓存是否存在
        /// <summary>
        /// 缓存是否存在
        /// </summary>
        /// <param name="serverlist">IP端口列表</param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static bool CacheIsExists(ArrayList serverlist, string poolName, string key)
        {
            MemcachedClient mc = CreateServer(serverlist, poolName);

            if (mc.KeyExists(key))
            {
                return true;
            }
            else
            {
                return false;
            }

        }
        #endregion

        #region 添加缓存

        #region 添加缓存(键不存在则添加,键存在则不能添加)
        /// <summary>
        /// 添加缓存(键不存在则添加,键存在则不能添加)
        /// </summary>
        /// <param name="serverlist">IP端口列表</param>
        /// <param name="poolName">连接池名称</param>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="minutes">过期分钟数</param>
        /// <returns></returns>
        public static bool AddCache(ArrayList serverlist, string poolName, string key, string value, int minutes)
        {
            MemcachedClient mc = CreateServer(serverlist, poolName);
            return mc.Add(key, value, DateTime.Now.AddMinutes(minutes));
        }
        #endregion

        #region 添加缓存(键不存在则添加,键存在则不能添加)
        /// <summary>
        /// 添加缓存(键不存在则添加,键存在则不能添加)
        /// </summary>
        /// <param name="serverlist">IP端口列表</param>
        /// <param name="poolName">连接池名称</param>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="minutes">过期分钟数</param>
        /// <returns></returns>
        public static bool AddCache(ArrayList serverlist, string poolName, string key, object value, int minutes)
        {
            MemcachedClient mc = CreateServer(serverlist, poolName);
            return mc.Add(key, value, DateTime.Now.AddMinutes(minutes));
        }
        #endregion

        #region 添加缓存(键不存在则添加,键存在则覆盖)
        /// <summary>
        /// 添加缓存(键不存在则添加,键存在则覆盖)
        /// </summary>
        /// <param name="serverlist">IP端口列表</param>
        /// <param name="poolName">连接池名称</param>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="minutes">过期分钟数</param>
        /// <returns></returns>
        public static bool SetCache(ArrayList serverlist, string poolName, string key, string value, int minutes)
        {
            MemcachedClient mc = CreateServer(serverlist, poolName);
            return mc.Set(key, value, DateTime.Now.AddMinutes(minutes));
        }
        #endregion

        #region 添加缓存(键不存在则添加,键存在则覆盖)
        /// <summary>
        /// 添加缓存(键不存在则添加,键存在则覆盖) object 类型
        /// </summary>
        /// <param name="serverlist">IP端口列表</param>
        /// <param name="poolName">连接池名称</param>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="minutes">过期分钟数</param>
        /// <returns></returns>
        public static bool SetCache(ArrayList serverlist, string poolName, string key, object value, int minutes)
        {
            MemcachedClient mc = CreateServer(serverlist, poolName);
            return mc.Set(key, value, DateTime.Now.AddMinutes(minutes));
        }
        #endregion

        #endregion

        #region 替换缓存

        #region 替换缓存(键存在的才能替换,不存在则不替换)
        /// <summary>
        /// 替换缓存(键存在的才能替换,不存在则不替换)
        /// </summary>
        /// <param name="serverlist">IP端口列表</param>
        /// <param name="poolName">连接池名称</param>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="minutes">过期分钟数</param>
        /// <returns></returns>
        public static bool ReplaceCache(ArrayList serverlist, string poolName, string key, string value, int minutes)
        {
            MemcachedClient mc = CreateServer(serverlist, poolName);
            return mc.Replace(key, value, DateTime.Now.AddMinutes(minutes));
        }
        #endregion

        #endregion

        #region 获取缓存

        #region 获取单个键对应的缓存
        /// <summary>
        /// 获取单个键对应的缓存
        /// </summary>
        /// <param name="serverlist">IP端口列表</param>
        /// <param name="poolName">连接池名称</param>
        /// <param name="key"></param> 
        /// <returns></returns>
        public static object GetCache(ArrayList serverlist, string poolName, string key)
        {
            MemcachedClient mc = CreateServer(serverlist, poolName);
            if (mc.KeyExists(key))
            {
                return mc.Get(key);
            }
            else
            {
                return "";
            }
        }
        #endregion

        #region 获取键数组对应的值
        /// <summary>
        /// 获取键数组对应的值
        /// </summary>
        /// <param name="serverlist">IP端口列表</param>
        /// <param name="poolName">连接池名称</param>
        /// <param name="keys">键列表</param>
        /// <returns>Hashtable键值对</returns>
        public static Hashtable GetCacheHt(ArrayList serverlist, string poolName, string[] keys)
        {
            MemcachedClient mc = CreateServer(serverlist, poolName);
            return mc.GetMultiple(keys);
        }
        #endregion

        #region 获取键数组对应的值
        /// <summary>
        /// 获取键数组对应的值
        /// </summary>
        /// <param name="serverlist">IP端口列表</param>
        /// <param name="poolName">连接池名称</param>
        /// <param name="keys">键列表</param>
        /// <returns>值的数组(不包含键)</returns>
        public static object[] GetCacheList(ArrayList serverlist, string poolName, string[] keys)
        {
            MemcachedClient mc = CreateServer(serverlist, poolName);
            object[] list = mc.GetMultipleArray(keys);
            ArrayList returnList = new ArrayList();
            for (int i = 0; i < list.Length; i++)
            {
                if (list[i] != null)
                {
                    returnList.Add(list[i]);
                }
            }
            return returnList.ToArray();
        }
        #endregion

        #endregion

        #region 删除缓存
        /// <summary>
        /// 删除缓存
        /// </summary>
        /// <param name="serverlist">IP端口列表</param>
        /// <param name="poolName">连接池名称</param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static bool DelCache(ArrayList serverlist, string poolName, string key)
        {
            MemcachedClient mc = CreateServer(serverlist, poolName);
            return mc.Delete(key);
        }
        #endregion

        #region 清空所有缓存
        /// <summary>
        /// 清空所有缓存
        /// </summary>
        /// <param name="serverlist">IP端口列表</param>
        /// <param name="poolName">连接池名称</param>
        /// <returns></returns>
        public static bool FlushAll(ArrayList serverlist, string poolName)
        {
            MemcachedClient mc = CreateServer(serverlist, poolName);
            return mc.FlushAll();
        }
        #endregion

    }
}
View Code
{
        private static readonly ILog Logger = LogManager.GetCurrentClassLogger();

        private readonly MemcachedClient _cache;

        public MemcachedCachePolicy()
        {
            _cache = MemcachedClient.GetInstance("MemcachedConfig");
            
            _cache.MaxPoolSize = 10000;
        }

        public void Add<T>(string key, T value)
        {
            if (_cache.Set(key, value))
            {
                Logger.Debug("Set _cache for key successed, key[" + key + "]");
            }
            else
            {
                Logger.Debug("Set _cache for key failed");
            }
        }

        public void Add<T>(string key, T value, DateTime dt)
        {
            _cache.Set(key, value, dt);
        }

        public T Get<T>(string key)
        {
            try
            {
                return (T)_cache.Get(key);
            }
            catch (Exception e)
            {
                Logger.Debug("Get _cache for key failed, key[" + key + "]", e);
                _cache.Delete(key);
                return default(T);
            }
        }

        public void Add(string key, object value)
        {
            _cache.Set(key, value);
        }

        public void Add(string key, object value, DateTime dt)
        {
            _cache.Set(key, value, dt);
        }

        public object Get(string key)
        {
            return _cache.Get(key);
        }

        public void Delete(string key)
        {
            _cache.Delete(key);
        }
    }
View Code
using Memcached.ClientLibrary;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CZBK.ItcastOA.Common
{
   public class MemcacheHelper
    {
       private static readonly MemcachedClient mc = null;

       static MemcacheHelper()
       {
           //最好放在配置文件中
           string[] serverlist = { "127.0.0.1:11211", "10.0.0.132:11211" };

           //初始化池
           SockIOPool pool = SockIOPool.GetInstance();
           pool.SetServers(serverlist);

           pool.InitConnections = 3;
           pool.MinConnections = 3;
           pool.MaxConnections = 5;

           pool.SocketConnectTimeout = 1000;
           pool.SocketTimeout = 3000;

           pool.MaintenanceSleep = 30;
           pool.Failover = true;

           pool.Nagle = false;
           pool.Initialize();

           // 获得客户端实例
            mc = new MemcachedClient();
           mc.EnableCompression = false;
       }
       /// <summary>
       /// 存储数据
       /// </summary>
       /// <param name="key"></param>
       /// <param name="value"></param>
       /// <returns></returns>
       public static bool Set(string key,object value)
       {
          return mc.Set(key, value);
       }
       public static bool Set(string key, object value,DateTime time)
       {
           return mc.Set(key, value,time);
       }
       /// <summary>
       /// 获取数据
       /// </summary>
       /// <param name="key"></param>
       /// <returns></returns>
       public static object Get(string key)
       {
           return mc.Get(key);
       }
       /// <summary>
       /// 删除
       /// </summary>
       /// <param name="key"></param>
       /// <returns></returns>
       public static bool Delete(string key)
       {
           if (mc.KeyExists(key))
           {
               return mc.Delete(key);

           }
           return false;

       }
    }
}
View Code

 多线程处理 lucene.net  单例模式

using CZBK.ItcastOA.Model.EnumType;
using Lucene.Net.Analysis.PanGu;
using Lucene.Net.Documents;
using Lucene.Net.Index;
using Lucene.Net.Store;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Web;

namespace CZBK.ItcastOA.WebApp.Models
{
    public sealed class IndexManager
    {
        //不用写跟新方法了,因为添加的时候,是先删除然后添加
        //单列模式 sealed 不允许被继承
        // 只允许在自己的类中 创建私有的构造函数
        //readonly 不允许改 只读的
        
        private static readonly IndexManager indexManager = new IndexManager();
        private IndexManager()
        {
        //创建私有的构造函数 保证不被外部new
        }
        public static IndexManager GetInstance()
        {
            return indexManager;
        }
        public Queue<ViewModelContent> queue = new Queue<ViewModelContent>();
        /// <summary>
        /// 向队列中添加数据
        /// </summary>
        /// <param name="id"></param>
        /// <param name="title"></param>
        /// <param name="content"></param>
        public void AddQueue(int id, string title, string content)
        {
            ViewModelContent viewModel = new ViewModelContent();
            viewModel.Id = id;
            viewModel.Title = title;
            viewModel.Content = content;
            viewModel.LuceneTypeEnum = LuceneTypeEnum.Add; 
            queue.Enqueue(viewModel);
        }
        /// <summary>
        /// 要删除的数据
        /// </summary>
        /// <param name="id"></param>
        public void DeleteQueue(int id)
        {
            ViewModelContent viewModel = new ViewModelContent();
            viewModel.Id = id;
            viewModel.LuceneTypeEnum = LuceneTypeEnum.Delete;
            queue.Enqueue(viewModel);
        }
      

        /// <summary>
        /// 开始一个线程
        /// </summary>
        public void StartThread()
        {
            Thread thread = new Thread(WriteIndexContent);
            thread.IsBackground = true;
            thread.Start();
        }
        /// <summary>
        /// 检查队列中是否有数据,如果有数据获取。
        /// </summary>
        private void WriteIndexContent()
        {
            while (true)
            {
                if (queue.Count > 0)
                {
                    CreateIndexContent();
                }
                else
                {
                    Thread.Sleep(3000);
                }
            }
        }
        private void CreateIndexContent()
        {
            string indexPath = @"C:lucenedir";//注意和磁盘上文件夹的大小写一致,否则会报错。将创建的分词内容放在该目录下。//将路径写到配置文件中。
            FSDirectory directory = FSDirectory.Open(new DirectoryInfo(indexPath), new NativeFSLockFactory());//指定索引文件(打开索引目录) FS指的是就是FileSystem
            bool isUpdate = IndexReader.IndexExists(directory);//IndexReader:对索引进行读取的类。该语句的作用:判断索引库文件夹是否存在以及索引特征文件是否存在。
            if (isUpdate)
            {
                //同时只能有一段代码对索引库进行写操作。当使用IndexWriter打开directory时会自动对索引库文件上锁。
                //如果索引目录被锁定(比如索引过程中程序异常退出),则首先解锁(提示一下:如果我现在正在写着已经加锁了,但是还没有写完,这时候又来一个请求,那么不就解锁了吗?这个问题后面会解决)
                if (IndexWriter.IsLocked(directory))
                {
                    IndexWriter.Unlock(directory);
                }
            }
            IndexWriter writer = new IndexWriter(directory, new PanGuAnalyzer(), !isUpdate, Lucene.Net.Index.IndexWriter.MaxFieldLength.UNLIMITED);//向索引库中写索引。这时在这里加锁。
           //如果队列中有数据,获取队列中的数据写到Lucene.Net中。
            while(queue.Count>0)
            {
                ViewModelContent viewModel=queue.Dequeue();
                writer.DeleteDocuments(new Term("Id",viewModel.Id.ToString()));//删除
                if (viewModel.LuceneTypeEnum == LuceneTypeEnum.Delete)
                {
                    continue;
                }
                Document document = new Document();//表示一篇文档。
                //Field.Store.YES:表示是否存储原值。只有当Field.Store.YES在后面才能用doc.Get("number")取出值来.Field.Index. NOT_ANALYZED:不进行分词保存
                document.Add(new Field("Id", viewModel.Id.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));

                //Field.Index. ANALYZED:进行分词保存:也就是要进行全文的字段要设置分词 保存(因为要进行模糊查询)

                //Lucene.Net.Documents.Field.TermVector.WITH_POSITIONS_OFFSETS:不仅保存分词还保存分词的距离。
                document.Add(new Field("Title", viewModel.Title, Field.Store.YES, Field.Index.ANALYZED, Lucene.Net.Documents.Field.TermVector.WITH_POSITIONS_OFFSETS));
                document.Add(new Field("Content", viewModel.Content, Field.Store.YES, Field.Index.ANALYZED, Lucene.Net.Documents.Field.TermVector.WITH_POSITIONS_OFFSETS));
                writer.AddDocument(document);

            }
            writer.Close();//会自动解锁。
            directory.Close();//不要忘了C
        }

    }
}
View Code

调用上面的单列

using CZBK.ItcastOA.WebApp.Models;
using log4net;
using Spring.Web.Mvc;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;

namespace CZBK.ItcastOA.WebApp
{
    // 注意: 有关启用 IIS6 或 IIS7 经典模式的说明,
    // 请访问 http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : SpringMvcApplication //System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            log4net.Config.XmlConfigurator.Configure();//读取了配置文件中关于Log4Net配置信息.
            IndexManager.GetInstance().StartThread();//开始线程扫描LuceneNet对应的数据队列。 这里就不能new了 因为你是单列模式  所以直接掉他的方法创建实例,他只允许自己的内部创建

            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            //开启一个线程,扫描异常信息队列。
            string filePath = Server.MapPath("/Log/");
            ThreadPool.QueueUserWorkItem((a) => {
                while (true)
                {
                    //判断一下队列中是否有数据
                    if (MyExceptionAttribute.ExecptionQueue.Count() > 0)
                    {
                        Exception ex=MyExceptionAttribute.ExecptionQueue.Dequeue();
                        if (ex != null)
                        {
                            //将异常信息写到日志文件中。
                            //string fileName = DateTime.Now.ToString("yyyy-MM-dd");
                            //File.AppendAllText(filePath+fileName+".txt",ex.ToString(),System.Text.Encoding.UTF8);
                            ILog logger = LogManager.GetLogger("errorMsg");
                            logger.Error(ex.ToString());
                        }
                        else
                        {
                            //如果队列中没有数据,休息
                            Thread.Sleep(3000);
                        }
                    }
                    else
                    {
                        //如果队列中没有数据,休息
                        Thread.Sleep(3000);
                    }
                }
            
            
            },filePath);

        }
       //异常处理的过滤器。
    }
}
View Code

测试上面的队列

using CZBK.ItcastOA.WebApp.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace CZBK.ItcastOA.WebApp.Controllers
{
    public class TestController : Controller
    {
        //
        // GET: /Test/

        public ActionResult Index()
        {
            return View();
        }
        public ActionResult ShowResult()
        {
            int a = 2;
            int b = 0;
            int c = a / b;
            return Content(c.ToString());
        }
        public ActionResult TestCreate()
        {
            Model.Books model = new Model.Books();
            model.AurhorDescription = "jlkfdjf";
            model.Author = "asfasd";
            model.CategoryId = 1;
            model.Clicks = 1;
            model.ContentDescription = "Ajax高级编程";
            model.EditorComment = "adfsadfsadf";
            model.ISBN = "111111111111111111";
            model.PublishDate = DateTime.Now;
            model.PublisherId = 72;
            model.Title = "Ajax";
            model.TOC = "aaaaaaaaaaaaaaaa";
            model.UnitPrice = 22.3m;
            model.WordsCount = 1234;
            //1.将数据先存储到数据库中。获取刚插入的数据的主键ID值。
            IndexManager.GetInstance().AddQueue(9999, model.Title, model.ContentDescription);//向队列中添加
            return Content("ok");
        }

    }
}
View Code

lucene.net 返回的时候 为什么只返回文档的编号  而不是吧整个文档返回?

节省内存,如果把符合结果的文档全部返回,那样占的内存就大了

拿到文档ID之后  在根据文档ID   单条搜索文档内容

此处我感觉  lucene是可以存文档内容的   看具体需求吧

区分同一from表单不同按钮提交

 当一个form表单 有两个提交按钮的时候怎么区别?  比如 “搜索”、“创建索引库”

根据 submit的值,点哪个提交哪个的值,另一个值是空

if(!string.IsNullOrEmpty(Request["btnSearth"])){}

Quartz.net

using Quartz;
using Quartz.Impl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CZBK.ItcastOA.QuartzNet
{
    class Program
    {
        static void Main(string[] args)
        {
            IScheduler sched;
            ISchedulerFactory sf = new StdSchedulerFactory();
            sched = sf.GetScheduler();
            //IndexJob为实现了IJob接口的类,执行的事情写在Execute方法内
            //job1:工作名字 随便写   group1:分组的组名  随便写
            JobDetail job = new JobDetail("job1", "group1", typeof(IndexJob));
            
            //5秒后开始第一次运行
            DateTime ts = TriggerUtils.GetNextGivenSecondDate(null, 5);
            
            //每隔5s执行一次/TimeSpan.FromHours(1);//一小时
            TimeSpan interval = TimeSpan.FromSeconds(5);
            
            //每若干小时运行一次,小时间隔由appsettings中的IndexIntervalHour参数指定
            //trigger1:触发器名字 随便写
            Trigger trigger = new SimpleTrigger("trigger1", "group1", "job1", "group1", ts, null,SimpleTrigger.RepeatIndefinitely, interval);

            sched.AddJob(job, true);
            sched.ScheduleJob(trigger);
            sched.Start();
            Console.ReadKey();
        }
    }
}
View Code
using Quartz;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CZBK.ItcastOA.QuartzNet
{
    /// <summary>
    /// 完成工作任务的定义。
    /// </summary>
   public class IndexJob:IJob
    {
       /// <summary>
       /// 将明细表中的数据插入到汇总表中。
       /// </summary>
       /// <param name="context"></param>
       IBLL.IKeyWordsRankService bll = new BLL.KeyWordsRankService();
       public void Execute(JobExecutionContext context)
        {
            //执行的工作
            bll.DeleteAllKeyWordsRank();
            bll.InsertKeyWordsRank();
        }
    }
}
View Code
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CZBK.ItcastOA.BLL
{
   public partial class KeyWordsRankService:BaseService<Model.KeyWordsRank>,IBLL.IKeyWordsRankService
    {
       /// <summary>
       /// 将统计的明细表的数据插入。
       /// </summary>
       /// <returns></returns>
        public bool InsertKeyWordsRank()
        {
            string sql = "insert into KeyWordsRank(Id,KeyWords,SearchCount) select newid(),KeyWords,count(*)  from SearchDetails where DateDiff(day,SearchDetails.SearchDateTime,getdate())<=7 group by SearchDetails.KeyWords";
            return this.CurrentDBSession.ExecuteSql(sql)>0;
        }
       /// <summary>
       /// 删除汇总中的数据。
       /// </summary>
       /// <returns></returns>
        public bool DeleteAllKeyWordsRank()
        {
            //用这句删除表中的数据是非常快的
            string sql = "truncate table KeyWordsRank";
           return this.CurrentDBSession.ExecuteSql(sql)>0;
        }
        public List<string> GetSearchMsg(string term)
        {
           //KeyWords like term%
            string sql = "select KeyWords from KeyWordsRank where KeyWords like @term";
           return this.CurrentDBSession.ExecuteQuery<string>(sql, new SqlParameter("@term",term+"%" ));
        }
    }
}
View Code

session原理

memcache  分布式session原理  创建缓存的唯一key  GUID  然后以cookie的形式存客户浏览器内存上,这就是原生session的原理 

队列:

dot.net 自带了队列  队列和栈相反,队列是先进 先出

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Web;
using System.Web.Mvc;

namespace CZBK.ItcastOA.WebApp.Models
{
    public class MyExceptionAttribute : HandleErrorAttribute
    {
        //静态的 保证在一个队列里,如果每次都new得话就不是一个队列了
        public static Queue<Exception> ExecptionQueue = new Queue<Exception>();
        /// <summary>
        /// 可以捕获异常数据
        /// </summary>
        /// <param name="filterContext"></param>
        public override void OnException(ExceptionContext filterContext)
        {
          
            base.OnException(filterContext);
            Exception ex = filterContext.Exception;
            //写到队列
            ExecptionQueue.Enqueue(ex);
            //跳转到错误页面.
            filterContext.HttpContext.Response.Redirect("/Error.html");
        }
    }
}
View Code

热词展示  

autocomplete 插件 效果 类似智能提示 当你在搜索框输入“你”  会提示“你好”“你好吗”等下拉一系列 你提供的词

WebService

socket通信

方法上又一个 [webMethod] 特性标签  证明别的程序可以调用该方法

soap 基于http协议 类似http协议 有请求头  请求体

另一个应用场景 SOA 面向服务编程  作为项目的服务层

WCF 协议就比较多了  http  tcp  契约:服务 消息 错误等四大契约

要引用 serviceModel 在接口上添加特性标签 [serviceContract](服务契约)   在方法上添加特性标签[Operationcontract](操作契约)

部署:IIS  控制台 winfor 等都可以  可以寄宿到多种程序

为了使AJAX或JS调用服务,必须标记服务的AspNet兼容模式为Allowed或Required。其次,操作契约必须标记为WebGet或WebInvoke,WebGet属性标记了一个可以用http get方法调用的操作,而WebInvoke属性标记了一个可以用http post方法调用的操作。

http://www.cnblogs.com/cokkiy/archive/2009/10/22/jsCallWCF.html

-- 垃圾堆

手动解耦 可以在web.config  配置dll  达到解耦效果

抽象工厂 通过反射

简单工厂 直接new

ztree:自己不用管层级关系,给一组json数组,主要根据pid分层

如果想给数据 可以创建一个ztree的的model  然后给model复制,然后序列化传给前台

savechange 设计模式:工作单元模式 :一个业务对多张表的操作,只连一次数据库,完成条记录的更新

简单工厂:返回父类或者接口的多种形态

抽象工厂:通过反射创建

单例:类似静态类  可以继承  扩展  延迟加载.....保证程序只new一次   比如队列 就可以放在单列里面

session跨域 也是用内存 cookie实现
webapi 图片分布式存储 nginx monodb QQ登录 工作流 图片延迟加载
Echarts NPOI t4 lucene.Net+盘古分词 fineui log4net json.net
Hbiulder 分布式session memcache redis Quartz.net soa aop 正则 ztree
队列 缓存 管道19事件
分布式session解决:唯一key cookie存到客户端

富文本  异步  json  序列化  ORM  二维码

clr (common language ruantian) 公共语言运行时 .net framwork

il .net语言转换为机器语言的额中间语言 伪汇编

数据库三范式
存储过程 触发器 设计模式

数据结构 二叉树 集合 图形
排序算法 冒泡等

 压力测试http://www.ikende.com/

原文地址:https://www.cnblogs.com/xiaoshi657/p/4060035.html