参考《MOSS中文档点击率统计的实现方法》一文,具体出处不太清楚,在网上搜到的,都没有标明出处或是原著,我也就不给出链接了,大家可以自己去搜一下。我按文中方法实现不成功,按照文中思路重新新写了一遍,原文中是通过修改Global.asax文件我发现这样没法调试(至少我这里没法调试,我这里总有点问题样的,工作流也没法附加进程调试,哪位高手能指定我一下为什么),于是改用HttpModule的方式,即可以实现,又可以调试。 具体步骤:
1.先为你的文档建立一个数字列,叫“浏览数”。
2.新建一个类库,我起名叫HitsCount,添加引用Microsoft.SharePoint,System.configuration以及System.Web
然后,将Class1.cs改名为HitsCountModule.cs
3. HitsCountModule.cs中内容如下
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
namespace HitsCount
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
public class HitsCountModule : IHttpModule
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
List<string> fileTypes;
public void Init(HttpApplication context)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
context.ResolveRequestCache += new EventHandler(context_ResolveRequestCache);
}
public void Dispose()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
}
void context_ResolveRequestCache(object sender, EventArgs e)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
try
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
HttpApplication httpApp = (HttpApplication)sender;
// 过滤不必要的请求
fileTypes = GetFileTypes();
if (!FiltrateFile(httpApp.Request.Url.AbsoluteUri))
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return;
}
// 从配置文件中获得计数器列的名称
string colName = "浏览数";//System.Configuration.ConfigurationManager.AppSettings["HitsColumnName"];
CountIncrement(colName, httpApp.Request.Url.AbsoluteUri, HttpContext.Current);
}
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
catch
{ }
}
void CountIncrement(string colName, string fileUrl, HttpContext content)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
SPWeb contextWeb = SPContext.Current.Web;
// 以管理员身份运行以下代码
Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(delegate()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
SPWeb web = SPContext.Current.Web;
try
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Microsoft.SharePoint.SPFile file = web.GetFile(fileUrl);
Microsoft.SharePoint.SPListItem item = file.Item;
Microsoft.SharePoint.SPList list = item.ParentList;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 备份值
bool allowUnsafeUpdates = web.AllowUnsafeUpdates;
bool enabledVersioning = list.EnableVersioning;
bool allowForceCheckout = list.ForceCheckout;
// 打开站点允许不安全的更新 否则无法更新
web.AllowUnsafeUpdates = true;
// 关闭版本纪录 否则每次修改都会产生一个新的版本
list.EnableVersioning = false;
// 关闭要求签出才可以修改文件 否则会要求每次更新时checkout文件
list.ForceCheckout = false;
list.Update();
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
string internalName = string.Empty;
int count = 0;
try
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
internalName = list.Fields[colName].InternalName;
int.TryParse(item[internalName].ToString(), out count);
count++;
item[internalName] = count;
item.Update();
}
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
catch
{ }
// 恢复SPWeb和SPList设置
web.AllowUnsafeUpdates = allowUnsafeUpdates;
list.EnableVersioning = enabledVersioning;
list.ForceCheckout = allowForceCheckout;
list.Update();
}
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
catch
{ }
finally
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (web != null)
web.Dispose();
}
});
}
// 获取支持文件类型
List<string> GetFileTypes()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
string typeString = ".docx,.doc"; // 也可以从配置文件读出来
List<string> types = new List<string>();
types.InsertRange(0, typeString.Split(','));
return types;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 验证是否是支持的文件类型
bool FiltrateFile(string fileUrl)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
string s = fileUrl.Substring(fileUrl.LastIndexOf('.'));
return fileTypes.Contains(s);
}
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
原文是用PreRequestHandlerExecute,我用PreRequestHandlerExecute是捕获不到我用word打开的.docx文件,于是我改用ResolveRequestCache方法后,解决。
4.建立强名称。右键项目-》属性-》签名-》把为程序集签名勾上,然后在下面下拉菜单中点“新建”,在弹出来的对话框中把“使用密码保护密钥文件”的小勾去掉,随便输入一个名字,确定。编译
5. 把编译好的dll拖入c:\windows\assembly目录下。也就是加入GAC,我是建立了一个bat文件,部署方便,bat文件内容如下
"%programfiles%\Microsoft Visual Studio 8\SDK\v2.0\Bin\gacutil.exe" -uf HitsCount
"%programfiles%\Microsoft Visual Studio 8\SDK\v2.0\Bin\gacutil.exe" -if bin\Debug\HitsCount.dll
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
iisreset
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
6.修改web.config文件,我的是在D:\Inetpub\wwwroot\wss\VirtualDirectories\80下,查找<httpModules>,在此节点下添加
<add name="HitsCount" type="HitsCount.HitsCountModule, HitsCount, Version=1.0.0.0, Culture=neutral, PublicKeyToken=239ba512823b3816"/>
其中PublicKeyToken值会不太一样,需要修改,可以在c:\windows\assembly下找到你拖进去的那个dll查属性就可以看到了。要么你就用Reflector来看吧。
完了后,在命令行输入iisreset重启IIS就完成了。
如果需要调试,直接在VS里,调试-》附加进程-》然后选择w3wp.exe。就可以设置断点并调试了。如果有多个w3wp.exe,可以在命令行下用iisapp命令来识别。
总结
这个方法虽然实现了浏览数的统计,可是也有一个问题,就是我们的“浏览数”是一个普通的列,用户只要有一定的权限就能修改这个列的值。这个问题可以通过自定义Field来实现,不过这类文章太多了,SDK里也有个很好的例子。小弟第一次在这里发随笔,平时说话经常语无论次,写出来的东西估计也是,大家砖头准备好,现一下就好,别真砸过来哈。
==============================================