Log Viewer(MVC)
使用MVC开发的日志在线管理表单,支持内容分页、按目录读取文件、配置操作权限等;
效果图:
BLL Code:

public class DiskLog : ILog
{
public int CalcTotalPage(long totalCount, int pageSize)
{
if (totalCount % pageSize == 0)
return (int)(totalCount / pageSize);
else
return (int)(totalCount / pageSize + 1);
}
/// <summary>
/// Paging Read File
/// </summary>
/// <param name="fileName"></param>
/// <param name="pageIndex"></param>
/// <param name="pageSize"></param>
/// <returns></returns>
public string ReadFile(string fileName, int pageIndex, int pageSize)
{
FileStream fs = null;
StreamReader sr = null;
Pagination<string> page = new Pagination<string>();
try
{
fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
sr = new StreamReader(fs);
int arrSize = pageSize;
long totalByte = fs.Length;
if (pageSize > totalByte)
arrSize = (int)totalByte;
else if ((pageIndex * pageSize) > totalByte)
arrSize = 0;
else if ((pageIndex * pageSize) < totalByte && CalcTotalPage(totalByte, pageSize) == pageIndex)
arrSize = (int)(totalByte - (pageIndex * pageSize));
if (arrSize > 0)
{
char[] fileContent = new char[arrSize];
int offset = (pageSize > totalByte) ? 0 : pageIndex * pageSize;
sr.BaseStream.Seek(offset, SeekOrigin.Begin);
sr.ReadBlock(fileContent, 0, arrSize);
page.CurrentPageIndex = pageIndex;
page.PageCount = CalcTotalPage(totalByte, pageSize);
page.TotalCount = totalByte;
page.Data = new string(fileContent);
Array.Clear(fileContent, 0, fileContent.Length);
page.PageSize = pageSize;
page.CurrentPageIndex = pageIndex;
}
}
catch (Exception ex)
{
}
finally
{
if (sr != null)
{
sr.Close();
sr.Dispose();
}
if (fs != null)
{
fs.Close();
fs.Dispose();
}
}
return page.ToJson();
}
/// <summary>
///Get File List
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public string[] GetFileList(string dirPath)
{
if (Directory.Exists(dirPath))
{
DirectoryInfo dir = new DirectoryInfo(dirPath);
FileInfo[] files = dir.GetFiles("*.*");
string[] fileNames = new string[files.Length];
int i = 0;
foreach (FileInfo fileInfo in files)
{
fileNames[i] = fileInfo.Name;
i++;
}
return fileNames;
}
else
{
return null;
}
}
/// <summary>
/// Read File
/// </summary>
/// <param name="filename"></param>
/// <returns></returns>
public string ReadFile(string filename)
{
StreamReader sr = null;
try
{
sr = File.OpenText(filename);
string data = "{\"Data\":\"" + Microsoft.JScript.GlobalObject.escape(sr.ReadToEnd()) + "\"}";
return data;
}
catch (Exception ex)
{
return ex.Message;
}
finally
{
if (sr != null)
{
sr.Close();
sr.Dispose();
}
}
}
/// <summary>
/// Delete File
/// </summary>
/// <param name="filepath"></param>
public bool DeleteFile(string filepath)
{
try
{
File.Delete(filepath);
return true;
}
catch
{
return false;
}
}
/// <summary>
/// Save File
/// </summary>
/// <param name="filename"></param>
/// <param name="content"></param>
public bool SaveFile(string filename, string content)
{
try
{
System.IO.File.WriteAllText(filename, content);
return true;
}
catch
{
return false;
}
}
/// <summary>
/// Clear File
/// </summary>
/// <param name="filename"></param>
public bool ClearFile(string filename)
{
try
{
File.WriteAllText(filename, "");
return true;
}
catch
{
return false;
}
}
}
{
public int CalcTotalPage(long totalCount, int pageSize)
{
if (totalCount % pageSize == 0)
return (int)(totalCount / pageSize);
else
return (int)(totalCount / pageSize + 1);
}
/// <summary>
/// Paging Read File
/// </summary>
/// <param name="fileName"></param>
/// <param name="pageIndex"></param>
/// <param name="pageSize"></param>
/// <returns></returns>
public string ReadFile(string fileName, int pageIndex, int pageSize)
{
FileStream fs = null;
StreamReader sr = null;
Pagination<string> page = new Pagination<string>();
try
{
fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
sr = new StreamReader(fs);
int arrSize = pageSize;
long totalByte = fs.Length;
if (pageSize > totalByte)
arrSize = (int)totalByte;
else if ((pageIndex * pageSize) > totalByte)
arrSize = 0;
else if ((pageIndex * pageSize) < totalByte && CalcTotalPage(totalByte, pageSize) == pageIndex)
arrSize = (int)(totalByte - (pageIndex * pageSize));
if (arrSize > 0)
{
char[] fileContent = new char[arrSize];
int offset = (pageSize > totalByte) ? 0 : pageIndex * pageSize;
sr.BaseStream.Seek(offset, SeekOrigin.Begin);
sr.ReadBlock(fileContent, 0, arrSize);
page.CurrentPageIndex = pageIndex;
page.PageCount = CalcTotalPage(totalByte, pageSize);
page.TotalCount = totalByte;
page.Data = new string(fileContent);
Array.Clear(fileContent, 0, fileContent.Length);
page.PageSize = pageSize;
page.CurrentPageIndex = pageIndex;
}
}
catch (Exception ex)
{
}
finally
{
if (sr != null)
{
sr.Close();
sr.Dispose();
}
if (fs != null)
{
fs.Close();
fs.Dispose();
}
}
return page.ToJson();
}
/// <summary>
///Get File List
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public string[] GetFileList(string dirPath)
{
if (Directory.Exists(dirPath))
{
DirectoryInfo dir = new DirectoryInfo(dirPath);
FileInfo[] files = dir.GetFiles("*.*");
string[] fileNames = new string[files.Length];
int i = 0;
foreach (FileInfo fileInfo in files)
{
fileNames[i] = fileInfo.Name;
i++;
}
return fileNames;
}
else
{
return null;
}
}
/// <summary>
/// Read File
/// </summary>
/// <param name="filename"></param>
/// <returns></returns>
public string ReadFile(string filename)
{
StreamReader sr = null;
try
{
sr = File.OpenText(filename);
string data = "{\"Data\":\"" + Microsoft.JScript.GlobalObject.escape(sr.ReadToEnd()) + "\"}";
return data;
}
catch (Exception ex)
{
return ex.Message;
}
finally
{
if (sr != null)
{
sr.Close();
sr.Dispose();
}
}
}
/// <summary>
/// Delete File
/// </summary>
/// <param name="filepath"></param>
public bool DeleteFile(string filepath)
{
try
{
File.Delete(filepath);
return true;
}
catch
{
return false;
}
}
/// <summary>
/// Save File
/// </summary>
/// <param name="filename"></param>
/// <param name="content"></param>
public bool SaveFile(string filename, string content)
{
try
{
System.IO.File.WriteAllText(filename, content);
return true;
}
catch
{
return false;
}
}
/// <summary>
/// Clear File
/// </summary>
/// <param name="filename"></param>
public bool ClearFile(string filename)
{
try
{
File.WriteAllText(filename, "");
return true;
}
catch
{
return false;
}
}
}
Controller Code:

public class LogViewerController : Controller
{
[HttpGet]
public ActionResult Index()
{
return View();
}
/// <summary>
/// Get File Tree Data
/// </summary>
/// <returns></returns>
public string GetTreeData()
{
StringBuilder treeJson = new StringBuilder();
treeJson.Append("[");
int index = 0;
var lstGroup = GetLogGroups();
treeJson.Append("{\"id\":" + index + ",\"text\":\"Root\",\"iconCls\":\"icon-save\",\"state\":\"open\"");
if (lstGroup.Count > 0)
treeJson.Append(",\"children\":[");
index = index + 1;
foreach (var group in lstGroup)
{
treeJson.Append("{\"id\":" + index + ",\"text\":\"" + group.GroupName + "\",\"iconCls\":\"icon-save\",\"state\":\"open\"");
index++;
if (group.IsAllFile == false && group.LogItemCollection.Count > 0)
{
treeJson.Append(",\"children\":[");
// Get All Item
foreach (var item in group.LogItemCollection)
{
treeJson.Append("{\"id\":" + index + ",\"text\":\"" + item.Name + "\",\"attributes\":[{\"fullName\":\"" + HttpUtility.JavaScriptStringEncode(item.FullName) + "\",\"CanPaging\":\"" + item.CanPaging + "\",\"CanModify\":\"" + item.CanModify + "\",\"CanClear\":\"" + item.CanClear + "\",\"CanDelete\":\"" + item.CanDelete + "\"}],\"iconCls\":\"icon-save\",\"state\":\"open\"},");
index++;
}
treeJson.Remove(treeJson.Length - 1, 1);
treeJson.Append("]");
}
else
{
Log.DiskLog log = new Log.DiskLog();
string[] arrFileName = log.GetFileList(group.DirectoryPath);
if (arrFileName != null && arrFileName.Length > 0)
{
treeJson.Append(",\"children\":[");
foreach (var fileName in arrFileName)
{
string fullName = group.DirectoryPath + "\\" + fileName;
treeJson.Append("{\"id\":" + index + ",\"text\":\"" + fileName + "\",\"attributes\":[{\"fullName\":\"" + HttpUtility.JavaScriptStringEncode(fullName) + "\",\"CanPaging\":\"" + group.CanPaging + "\",\"CanModify\":\"" + group.CanModify + "\",\"CanClear\":\"" + group.CanClear + "\",\"CanDelete\":\"" + group.CanDelete + "\"}],\"iconCls\":\"icon-save\",\"state\":\"open\"},");
index++;
}
treeJson.Remove(treeJson.Length - 1, 1);
treeJson.Append("]");
}
}
treeJson.Append("},");
}
if (lstGroup.Count > 0)
{
treeJson.Remove(treeJson.Length - 1, 1);
treeJson.Append("]}");
}
treeJson.Append("]");
return treeJson.ToString();
}
/// <summary>
/// Update file content
/// </summary>
/// <param name="filename">target file path</param>
/// <param name="content"></param>
/// <returns></returns>
[ValidateInput(false)]
public string Modify(string filename, string content)
{
Log.DiskLog log = new Log.DiskLog();
// save file
bool isSuccee = log.SaveFile(filename, content);
string message = isSuccee ? ("Modify Succeed!") : ("Modify error!");
return message;
}
/// <summary>
/// Clear file content
/// </summary>
/// <param name="filename">target file path</param>
/// <returns></returns>
public string Clear(string filename)
{
Log.DiskLog log = new Log.DiskLog();
// clear file
bool isSuccee = log.ClearFile(filename);
string message = isSuccee ? ("Clear succeed!") : ("Clear error!");
return message;
}
/// <summary>
/// Delete file
/// </summary>
/// <param name="filename">target file path</param>
/// <returns></returns>
public string Delete(string filename)
{
Log.DiskLog log = new Log.DiskLog();
// delete file
bool isSuccee = log.DeleteFile(filename);
string message = isSuccee ? ("Delete succeed!") : ("Delete error!");
return message;
}
/// <summary>
/// Get file content by file path
/// </summary>
/// <param name="filePath">target file path</param>
/// <returns>file content</returns>
public string ReadFile(string filename, int pageIndex, int pageSize, bool canPaging)
{
Log.DiskLog log = new Log.DiskLog();
if (canPaging)
return log.ReadFile(filename, pageIndex, pageSize);
else
return log.ReadFile(filename);
}
public bool IsRelativePath(string path)
{
return path.Contains("~/");
}
public bool GetNodeBoolAttr(XmlNode node, string attrName)
{
string sIsTrue = (node.Attributes[attrName] != null) ? node.Attributes[attrName].Value : "false";
bool isTrue = false;
bool.TryParse(sIsTrue, out isTrue);
return isTrue;
}
public string GetNodeStringAttr(XmlNode node, string attrName)
{
string sValue = (node.Attributes[attrName] != null) ? node.Attributes[attrName].Value : string.Empty;
return sValue;
}
/// <summary>
/// Get Log configuration return log group
/// </summary>
/// <returns></returns>
private List<LogGroup> GetLogGroups()
{
List<LogGroup> lstLogGroup = new List<LogGroup>();
string logconfigpath = System.Configuration.ConfigurationManager.AppSettings["LogConfig"];// Server.MapPath("~/") + "Log.config"; //
// check path
if (IsRelativePath(logconfigpath))
logconfigpath = Server.MapPath(logconfigpath);
XmlDocument doc = new XmlDocument();
try
{
doc.Load(logconfigpath);
var root = doc.SelectSingleNode("//root");
foreach (XmlNode groupNode in root.ChildNodes)
{
if (groupNode.Name == "loggroup")
{
string groupName = GetNodeStringAttr(groupNode, "name");
string dirPath = GetNodeStringAttr(groupNode, "dirpath");
if (IsRelativePath(dirPath))
dirPath = Server.MapPath(dirPath);
bool isAllFile = GetNodeBoolAttr(groupNode, "isallfile");
bool groupCanPaging = GetNodeBoolAttr(groupNode, "CanPaging");
bool groupCanModify = GetNodeBoolAttr(groupNode, "CanModify");
bool groupCanClear = GetNodeBoolAttr(groupNode, "CanClear");
bool groupCanDelete = GetNodeBoolAttr(groupNode, "CanDelete");
List<LogItem> lstLogItem = new List<LogItem>();
foreach (XmlNode itemNode in groupNode)
{
if (itemNode.Name == "logitem")
{
LogItem logItem = new LogItem();
string itemName = GetNodeStringAttr(itemNode, "name");
string fullName = GetNodeStringAttr(itemNode, "fullname");
bool canPaging = GetNodeBoolAttr(itemNode, "CanPaging");
bool canModify = GetNodeBoolAttr(itemNode, "CanModify");
bool canClear = GetNodeBoolAttr(itemNode, "CanClear");
bool canDelete = GetNodeBoolAttr(itemNode, "CanDelete");
if (IsRelativePath(fullName))
fullName = Server.MapPath(fullName);
logItem.Name = itemName;
logItem.FullName = fullName;
logItem.CanPaging = canPaging;
logItem.CanModify = canModify;
logItem.CanClear = canClear;
logItem.CanDelete = canDelete;
// Add to lstLogItem
lstLogItem.Add(logItem);
}
}
LogGroup logGroup = new LogGroup();
logGroup.GroupName = groupName;
logGroup.DirectoryPath = dirPath;
logGroup.IsAllFile = isAllFile;
logGroup.LogItemCollection = lstLogItem;
logGroup.CanPaging = groupCanPaging;
logGroup.CanModify = groupCanModify;
logGroup.CanClear = groupCanClear;
logGroup.CanDelete = groupCanDelete;
// Add to lstLogGroup
lstLogGroup.Add(logGroup);
}
}
}
catch (Exception ex)
{ }
return lstLogGroup;
}
}
{
[HttpGet]
public ActionResult Index()
{
return View();
}
/// <summary>
/// Get File Tree Data
/// </summary>
/// <returns></returns>
public string GetTreeData()
{
StringBuilder treeJson = new StringBuilder();
treeJson.Append("[");
int index = 0;
var lstGroup = GetLogGroups();
treeJson.Append("{\"id\":" + index + ",\"text\":\"Root\",\"iconCls\":\"icon-save\",\"state\":\"open\"");
if (lstGroup.Count > 0)
treeJson.Append(",\"children\":[");
index = index + 1;
foreach (var group in lstGroup)
{
treeJson.Append("{\"id\":" + index + ",\"text\":\"" + group.GroupName + "\",\"iconCls\":\"icon-save\",\"state\":\"open\"");
index++;
if (group.IsAllFile == false && group.LogItemCollection.Count > 0)
{
treeJson.Append(",\"children\":[");
// Get All Item
foreach (var item in group.LogItemCollection)
{
treeJson.Append("{\"id\":" + index + ",\"text\":\"" + item.Name + "\",\"attributes\":[{\"fullName\":\"" + HttpUtility.JavaScriptStringEncode(item.FullName) + "\",\"CanPaging\":\"" + item.CanPaging + "\",\"CanModify\":\"" + item.CanModify + "\",\"CanClear\":\"" + item.CanClear + "\",\"CanDelete\":\"" + item.CanDelete + "\"}],\"iconCls\":\"icon-save\",\"state\":\"open\"},");
index++;
}
treeJson.Remove(treeJson.Length - 1, 1);
treeJson.Append("]");
}
else
{
Log.DiskLog log = new Log.DiskLog();
string[] arrFileName = log.GetFileList(group.DirectoryPath);
if (arrFileName != null && arrFileName.Length > 0)
{
treeJson.Append(",\"children\":[");
foreach (var fileName in arrFileName)
{
string fullName = group.DirectoryPath + "\\" + fileName;
treeJson.Append("{\"id\":" + index + ",\"text\":\"" + fileName + "\",\"attributes\":[{\"fullName\":\"" + HttpUtility.JavaScriptStringEncode(fullName) + "\",\"CanPaging\":\"" + group.CanPaging + "\",\"CanModify\":\"" + group.CanModify + "\",\"CanClear\":\"" + group.CanClear + "\",\"CanDelete\":\"" + group.CanDelete + "\"}],\"iconCls\":\"icon-save\",\"state\":\"open\"},");
index++;
}
treeJson.Remove(treeJson.Length - 1, 1);
treeJson.Append("]");
}
}
treeJson.Append("},");
}
if (lstGroup.Count > 0)
{
treeJson.Remove(treeJson.Length - 1, 1);
treeJson.Append("]}");
}
treeJson.Append("]");
return treeJson.ToString();
}
/// <summary>
/// Update file content
/// </summary>
/// <param name="filename">target file path</param>
/// <param name="content"></param>
/// <returns></returns>
[ValidateInput(false)]
public string Modify(string filename, string content)
{
Log.DiskLog log = new Log.DiskLog();
// save file
bool isSuccee = log.SaveFile(filename, content);
string message = isSuccee ? ("Modify Succeed!") : ("Modify error!");
return message;
}
/// <summary>
/// Clear file content
/// </summary>
/// <param name="filename">target file path</param>
/// <returns></returns>
public string Clear(string filename)
{
Log.DiskLog log = new Log.DiskLog();
// clear file
bool isSuccee = log.ClearFile(filename);
string message = isSuccee ? ("Clear succeed!") : ("Clear error!");
return message;
}
/// <summary>
/// Delete file
/// </summary>
/// <param name="filename">target file path</param>
/// <returns></returns>
public string Delete(string filename)
{
Log.DiskLog log = new Log.DiskLog();
// delete file
bool isSuccee = log.DeleteFile(filename);
string message = isSuccee ? ("Delete succeed!") : ("Delete error!");
return message;
}
/// <summary>
/// Get file content by file path
/// </summary>
/// <param name="filePath">target file path</param>
/// <returns>file content</returns>
public string ReadFile(string filename, int pageIndex, int pageSize, bool canPaging)
{
Log.DiskLog log = new Log.DiskLog();
if (canPaging)
return log.ReadFile(filename, pageIndex, pageSize);
else
return log.ReadFile(filename);
}
public bool IsRelativePath(string path)
{
return path.Contains("~/");
}
public bool GetNodeBoolAttr(XmlNode node, string attrName)
{
string sIsTrue = (node.Attributes[attrName] != null) ? node.Attributes[attrName].Value : "false";
bool isTrue = false;
bool.TryParse(sIsTrue, out isTrue);
return isTrue;
}
public string GetNodeStringAttr(XmlNode node, string attrName)
{
string sValue = (node.Attributes[attrName] != null) ? node.Attributes[attrName].Value : string.Empty;
return sValue;
}
/// <summary>
/// Get Log configuration return log group
/// </summary>
/// <returns></returns>
private List<LogGroup> GetLogGroups()
{
List<LogGroup> lstLogGroup = new List<LogGroup>();
string logconfigpath = System.Configuration.ConfigurationManager.AppSettings["LogConfig"];// Server.MapPath("~/") + "Log.config"; //
// check path
if (IsRelativePath(logconfigpath))
logconfigpath = Server.MapPath(logconfigpath);
XmlDocument doc = new XmlDocument();
try
{
doc.Load(logconfigpath);
var root = doc.SelectSingleNode("//root");
foreach (XmlNode groupNode in root.ChildNodes)
{
if (groupNode.Name == "loggroup")
{
string groupName = GetNodeStringAttr(groupNode, "name");
string dirPath = GetNodeStringAttr(groupNode, "dirpath");
if (IsRelativePath(dirPath))
dirPath = Server.MapPath(dirPath);
bool isAllFile = GetNodeBoolAttr(groupNode, "isallfile");
bool groupCanPaging = GetNodeBoolAttr(groupNode, "CanPaging");
bool groupCanModify = GetNodeBoolAttr(groupNode, "CanModify");
bool groupCanClear = GetNodeBoolAttr(groupNode, "CanClear");
bool groupCanDelete = GetNodeBoolAttr(groupNode, "CanDelete");
List<LogItem> lstLogItem = new List<LogItem>();
foreach (XmlNode itemNode in groupNode)
{
if (itemNode.Name == "logitem")
{
LogItem logItem = new LogItem();
string itemName = GetNodeStringAttr(itemNode, "name");
string fullName = GetNodeStringAttr(itemNode, "fullname");
bool canPaging = GetNodeBoolAttr(itemNode, "CanPaging");
bool canModify = GetNodeBoolAttr(itemNode, "CanModify");
bool canClear = GetNodeBoolAttr(itemNode, "CanClear");
bool canDelete = GetNodeBoolAttr(itemNode, "CanDelete");
if (IsRelativePath(fullName))
fullName = Server.MapPath(fullName);
logItem.Name = itemName;
logItem.FullName = fullName;
logItem.CanPaging = canPaging;
logItem.CanModify = canModify;
logItem.CanClear = canClear;
logItem.CanDelete = canDelete;
// Add to lstLogItem
lstLogItem.Add(logItem);
}
}
LogGroup logGroup = new LogGroup();
logGroup.GroupName = groupName;
logGroup.DirectoryPath = dirPath;
logGroup.IsAllFile = isAllFile;
logGroup.LogItemCollection = lstLogItem;
logGroup.CanPaging = groupCanPaging;
logGroup.CanModify = groupCanModify;
logGroup.CanClear = groupCanClear;
logGroup.CanDelete = groupCanDelete;
// Add to lstLogGroup
lstLogGroup.Add(logGroup);
}
}
}
catch (Exception ex)
{ }
return lstLogGroup;
}
}
UI Code:

@{
Layout = "";
}
<!DOCTYPE html>
<html>
<head>
<title>Log Index</title>
<link href="@Url.Content("~/Content/reset.css")" rel="stylesheet" type="text/css" />
<link href="@Url.Content("~/Content/Admin.css")" rel="stylesheet" type="text/css" />
<link href="@Url.Content("~/Content/easyui_themes/gray/easyui.css")" rel="stylesheet" type="text/css" />
<script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.easyui.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/Log.js")" type="text/javascript"></script>
<script type="text/javascript">
var sureDelete = 'Sure you want to delete?';
var confirm = 'Confirm';
var prompt = 'Prompt';
var selectFileError = 'Must select a item';
var selectMustFile = 'Select type must is file';
</script>
</head>
<body>
@using (Ajax.BeginForm(null))
{
@Html.ValidationSummary(true)
<table style="width: 98%; height: 98%;">
<tr>
<td>
<a id="lnkDelete" href="javascript:DeleteFile();" class="easyui-linkbutton">Delete</a>
<a id="lnkRefreshTree" href="javascript:TreeInit();" class="easyui-linkbutton">Refresh</a>
</td>
<td>
<strong>FileName:</strong><label id="lblFileName"></label>
</td>
<td style="text-align: right;">
<a id="lnkModify" href="javascript:Modify();" class="easyui-linkbutton">Modify</a>
<a id="lnkClear" href="javascript:Clear();" class="easyui-linkbutton">Clear</a>
<a id="lnkRefreshFile" href="javascript:OpenFile();" class="easyui-linkbutton">Refresh</a>
</td>
</tr>
<tr>
<td style="width: 20%; height: 100%; vertical-align: top">
<ul id="treeFile">
</ul>
</td>
<td colspan="2" style="width: 80%; height: 100%; vertical-align: top">
@Html.TextArea("txtContent", new { style = "height:500px;width:100%;" })
<div id="divPaging" style="text-align: right">
Show Page Size(byte)
<select id="sltPageSize">
<option value="1024">1024</option>
<option value="2048">2048</option>
<option value="4069">4069</option>
</select>
Total Page Size:<label id="lblMaxPageCount">0</label>
<a id="lnkPre" href="javascript:" class="easyui-linkbutton">Previous</a><a
id="lnkNext" href="javascript:" class="easyui-linkbutton">Next</a>
<input id="txtPageIndex" type="text" style="width: 40px; height: 12px" /><a id="lnkGo"
href="javascript:" class="easyui-linkbutton">Go</a>
</div>
</td>
</tr>
</table>
@*<div id="loading" style="position: fixed !important; position: absolute; top: 0;display:none;
left: 0; height: 100%; width: 100%; z-index: 999; background: #000 url(http://interjc.googlecode.com/svn/trunk/waterfall/img/load.gif) no-repeat center center;
opacity: 0.6; filter: alpha(opacity=60); font-size: 14px; line-height: 20px;">
<p id="loading-one" style="color: #fff; position: absolute; top: 50%; left: 50%;
margin: 20px 0 0 -50px; padding: 3px 10px;" onclick="javascript:Loaded()">
页面载入中..
</p>
</div> *@
}
</body>
</html>
Layout = "";
}
<!DOCTYPE html>
<html>
<head>
<title>Log Index</title>
<link href="@Url.Content("~/Content/reset.css")" rel="stylesheet" type="text/css" />
<link href="@Url.Content("~/Content/Admin.css")" rel="stylesheet" type="text/css" />
<link href="@Url.Content("~/Content/easyui_themes/gray/easyui.css")" rel="stylesheet" type="text/css" />
<script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.easyui.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/Log.js")" type="text/javascript"></script>
<script type="text/javascript">
var sureDelete = 'Sure you want to delete?';
var confirm = 'Confirm';
var prompt = 'Prompt';
var selectFileError = 'Must select a item';
var selectMustFile = 'Select type must is file';
</script>
</head>
<body>
@using (Ajax.BeginForm(null))
{
@Html.ValidationSummary(true)
<table style="width: 98%; height: 98%;">
<tr>
<td>
<a id="lnkDelete" href="javascript:DeleteFile();" class="easyui-linkbutton">Delete</a>
<a id="lnkRefreshTree" href="javascript:TreeInit();" class="easyui-linkbutton">Refresh</a>
</td>
<td>
<strong>FileName:</strong><label id="lblFileName"></label>
</td>
<td style="text-align: right;">
<a id="lnkModify" href="javascript:Modify();" class="easyui-linkbutton">Modify</a>
<a id="lnkClear" href="javascript:Clear();" class="easyui-linkbutton">Clear</a>
<a id="lnkRefreshFile" href="javascript:OpenFile();" class="easyui-linkbutton">Refresh</a>
</td>
</tr>
<tr>
<td style="width: 20%; height: 100%; vertical-align: top">
<ul id="treeFile">
</ul>
</td>
<td colspan="2" style="width: 80%; height: 100%; vertical-align: top">
@Html.TextArea("txtContent", new { style = "height:500px;width:100%;" })
<div id="divPaging" style="text-align: right">
Show Page Size(byte)
<select id="sltPageSize">
<option value="1024">1024</option>
<option value="2048">2048</option>
<option value="4069">4069</option>
</select>
Total Page Size:<label id="lblMaxPageCount">0</label>
<a id="lnkPre" href="javascript:" class="easyui-linkbutton">Previous</a><a
id="lnkNext" href="javascript:" class="easyui-linkbutton">Next</a>
<input id="txtPageIndex" type="text" style="width: 40px; height: 12px" /><a id="lnkGo"
href="javascript:" class="easyui-linkbutton">Go</a>
</div>
</td>
</tr>
</table>
@*<div id="loading" style="position: fixed !important; position: absolute; top: 0;display:none;
left: 0; height: 100%; width: 100%; z-index: 999; background: #000 url(http://interjc.googlecode.com/svn/trunk/waterfall/img/load.gif) no-repeat center center;
opacity: 0.6; filter: alpha(opacity=60); font-size: 14px; line-height: 20px;">
<p id="loading-one" style="color: #fff; position: absolute; top: 50%; left: 50%;
margin: 20px 0 0 -50px; padding: 3px 10px;" onclick="javascript:Loaded()">
页面载入中..
</p>
</div> *@
}
</body>
</html>
JS Code:

var fullName = "";
var currentPageIndex = 1;
var pageCount = 1;
var pageSize = 1024;
var canPaging = false;
function CheckPageIndex() {
var pageIndex = parseInt($("#txtPageIndex").val());
$("#lnkGo").attr('disabled', (isNaN(pageIndex) || pageIndex > pageCount));
}
$(document).ready(function () {
// init file tree
TreeInit();
$("#lnkPre").attr('disabled', (currentPageIndex == 1));
$("#lnkNext").attr('disabled', (currentPageIndex >= pageCount));
$("#sltPageSize").change(function () {
pageSize = $("#sltPageSize option:selected").val();
OpenFile();
});
if ($.browser.msie) {
$("#txtPageIndex").bind("propertychange", CheckPageIndex);
}
else {
$("#txtPageIndex").bind("blur", CheckPageIndex)
}
$("#txtPageIndex").val(currentPageIndex);
$("#lnkPre").click(function () {
currentPageIndex = currentPageIndex - 1;
OpenFile();
});
$("#lnkNext").click(function () {
currentPageIndex = currentPageIndex + 1;
OpenFile();
});
$("#lnkGo").click(function () {
currentPageIndex = parseInt($("#txtPageIndex").val());
OpenFile();
});
$("#divPaging").hide();
});
function TreeInit() {
// Loading('@this.T("Loading data...")');
$('#treeFile').tree({
url: '/LogViewer/GetTreeData',
onClick: function (node) {
if (node.attributes != undefined) {
fullName = decodeURI(node.attributes[0].fullName);
$("#lblFileName").text(fullName);
canPaging = node.attributes[0].CanPaging == "True";
var canModify = node.attributes[0].CanModify;
var canClear = node.attributes[0].CanClear;
var canDelete = node.attributes[0].CanDelete;
$("#lnkDelete").attr("disabled", canDelete == "False");
$("#lnkClear").attr("disabled", canClear == "False");
$("#lnkModify").attr("disabled", canModify == "False");
if (canPaging)
$("#divPaging").show();
else
$("#divPaging").hide();
currentPageIndex = 1;
OpenFile();
} else
$("#txtContent").val("");
},
onLoadSuccess: function (msg) {
// Loaded('@this.T("Complete!")');
}
});
// clear txtContext.Text
$("#txtContent").val("");
}
function DataCheck() {
var node = $('#treeFile').tree('getSelected');
if (node == null) {
$.messager.alert(prompt, selectFileError);
return false;
}
if (node.attributes == undefined) {
$.messager.alert(prompt, selectMustFile);
return false;
}
return true;
}
function Clear() {
if (DataCheck()) {
$.messager.confirm(confirm, sureDelete, function (r) {
if (r) {
$.ajax(
{
type: "Post",
url: "/LogViewer/Clear",
data: "filename=" + fullName,
success: function (returndata) {
// refresh txtContext.Text
currentPageIndex = 1;
OpenFile();
$.messager.alert(prompt, returndata);
}
});
}
});
}
}
function Modify() {
if (DataCheck()) {
var filename = fullName;
var content = $("#txtContent").val();
$.ajax(
{
type: "Post",
url: "/LogViewer/Modify",
data: "filename=" + filename + "&content=" + content,
success: function (returndata) {
$.messager.alert(prompt, returndata);
},
error: function (xhr, status, errMsg) {
// alert(errMsg.msg);
}
});
}
}
function OpenFile() {
if (DataCheck()) {
// Loading('@this.T("Loading data...")');
$.getJSON(
"/LogViewer/ReadFile?date=" + new Date(),
{ filename: fullName, pageIndex: currentPageIndex - 1, pageSize: pageSize, canPaging: canPaging },
function (data) {
if (canPaging) {
var content = unescape(data[0].Data);
pageCount = data[0].PageCount;
var totalCount = data[0].TotalCount;
$("#txtContent").val(content);
$("#lblMaxPageCount").text(pageCount);
$("#txtPageIndex").val(currentPageIndex);
$("#lnkPre").attr('disabled', (currentPageIndex == 1));
$("#lnkNext").attr('disabled', (currentPageIndex >= pageCount));
} else
{
var content = unescape(data.Data);
$("#txtContent").val(content);
}
// Loaded('@this.T("Complete!")');
});
}
}
function DeleteFile() {
if (DataCheck()) {
$.messager.confirm(confirm, sureDelete, function (r) {
if (r) {
$.ajax(
{
type: "Post",
url: "/LogViewer/Delete",
data: "filename=" + fullName,
success: function (returndata) {
// refresh file tree
TreeInit();
$.messager.alert(prompt, returndata);
}
});
}
});
}
}
var currentPageIndex = 1;
var pageCount = 1;
var pageSize = 1024;
var canPaging = false;
function CheckPageIndex() {
var pageIndex = parseInt($("#txtPageIndex").val());
$("#lnkGo").attr('disabled', (isNaN(pageIndex) || pageIndex > pageCount));
}
$(document).ready(function () {
// init file tree
TreeInit();
$("#lnkPre").attr('disabled', (currentPageIndex == 1));
$("#lnkNext").attr('disabled', (currentPageIndex >= pageCount));
$("#sltPageSize").change(function () {
pageSize = $("#sltPageSize option:selected").val();
OpenFile();
});
if ($.browser.msie) {
$("#txtPageIndex").bind("propertychange", CheckPageIndex);
}
else {
$("#txtPageIndex").bind("blur", CheckPageIndex)
}
$("#txtPageIndex").val(currentPageIndex);
$("#lnkPre").click(function () {
currentPageIndex = currentPageIndex - 1;
OpenFile();
});
$("#lnkNext").click(function () {
currentPageIndex = currentPageIndex + 1;
OpenFile();
});
$("#lnkGo").click(function () {
currentPageIndex = parseInt($("#txtPageIndex").val());
OpenFile();
});
$("#divPaging").hide();
});
function TreeInit() {
// Loading('@this.T("Loading data...")');
$('#treeFile').tree({
url: '/LogViewer/GetTreeData',
onClick: function (node) {
if (node.attributes != undefined) {
fullName = decodeURI(node.attributes[0].fullName);
$("#lblFileName").text(fullName);
canPaging = node.attributes[0].CanPaging == "True";
var canModify = node.attributes[0].CanModify;
var canClear = node.attributes[0].CanClear;
var canDelete = node.attributes[0].CanDelete;
$("#lnkDelete").attr("disabled", canDelete == "False");
$("#lnkClear").attr("disabled", canClear == "False");
$("#lnkModify").attr("disabled", canModify == "False");
if (canPaging)
$("#divPaging").show();
else
$("#divPaging").hide();
currentPageIndex = 1;
OpenFile();
} else
$("#txtContent").val("");
},
onLoadSuccess: function (msg) {
// Loaded('@this.T("Complete!")');
}
});
// clear txtContext.Text
$("#txtContent").val("");
}
function DataCheck() {
var node = $('#treeFile').tree('getSelected');
if (node == null) {
$.messager.alert(prompt, selectFileError);
return false;
}
if (node.attributes == undefined) {
$.messager.alert(prompt, selectMustFile);
return false;
}
return true;
}
function Clear() {
if (DataCheck()) {
$.messager.confirm(confirm, sureDelete, function (r) {
if (r) {
$.ajax(
{
type: "Post",
url: "/LogViewer/Clear",
data: "filename=" + fullName,
success: function (returndata) {
// refresh txtContext.Text
currentPageIndex = 1;
OpenFile();
$.messager.alert(prompt, returndata);
}
});
}
});
}
}
function Modify() {
if (DataCheck()) {
var filename = fullName;
var content = $("#txtContent").val();
$.ajax(
{
type: "Post",
url: "/LogViewer/Modify",
data: "filename=" + filename + "&content=" + content,
success: function (returndata) {
$.messager.alert(prompt, returndata);
},
error: function (xhr, status, errMsg) {
// alert(errMsg.msg);
}
});
}
}
function OpenFile() {
if (DataCheck()) {
// Loading('@this.T("Loading data...")');
$.getJSON(
"/LogViewer/ReadFile?date=" + new Date(),
{ filename: fullName, pageIndex: currentPageIndex - 1, pageSize: pageSize, canPaging: canPaging },
function (data) {
if (canPaging) {
var content = unescape(data[0].Data);
pageCount = data[0].PageCount;
var totalCount = data[0].TotalCount;
$("#txtContent").val(content);
$("#lblMaxPageCount").text(pageCount);
$("#txtPageIndex").val(currentPageIndex);
$("#lnkPre").attr('disabled', (currentPageIndex == 1));
$("#lnkNext").attr('disabled', (currentPageIndex >= pageCount));
} else
{
var content = unescape(data.Data);
$("#txtContent").val(content);
}
// Loaded('@this.T("Complete!")');
});
}
}
function DeleteFile() {
if (DataCheck()) {
$.messager.confirm(confirm, sureDelete, function (r) {
if (r) {
$.ajax(
{
type: "Post",
url: "/LogViewer/Delete",
data: "filename=" + fullName,
success: function (returndata) {
// refresh file tree
TreeInit();
$.messager.alert(prompt, returndata);
}
});
}
});
}
}
Log.config
<?xml version="1.0" encoding="utf-8" ?>
<root>
<loggroup name="log" dirpath="F:\Billy\src\CTBlazer\Bin\Log" isallfile="true" CanPaging="true" CanModify="false" CanClear="true" CanDelete="true">
</loggroup>
<loggroup name="config" dirpath="">
<logitem name="web.config" fullname="~/web.config" CanPaging="false" CanModify="true" CanClear="false" CanDelete="false"></logitem>
<logitem name="Log.config" fullname="~/Log.config" CanPaging="false" CanModify="true" CanClear="false" CanDelete="false"></logitem>
</loggroup>
</root>
<root>
<loggroup name="log" dirpath="F:\Billy\src\CTBlazer\Bin\Log" isallfile="true" CanPaging="true" CanModify="false" CanClear="true" CanDelete="true">
</loggroup>
<loggroup name="config" dirpath="">
<logitem name="web.config" fullname="~/web.config" CanPaging="false" CanModify="true" CanClear="false" CanDelete="false"></logitem>
<logitem name="Log.config" fullname="~/Log.config" CanPaging="false" CanModify="true" CanClear="false" CanDelete="false"></logitem>
</loggroup>
</root>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了