As per this MSDN article:
W3C Extended Log File Format (IIS 6.0)
It says cs(Referrer)
contains the REFERER information that can be read from the IIS log files.
I am trying to display the log information using an ASP.NET Repeater control:
<asp:Repeater ID="rptlIISLogEntries" runat="server">
...
...
<ItemTemplate>
<tr>
<td><%# Eval("time")%></td>
<td><%# Eval("cs(Referrer)")%></td>
</tr>
</ItemTemplate>
</asp:Repeater>
The line with Eval("cs(Referrer)"
throws an exception:
DataBinding:'System.Data.DataRowView' does not contain a property with the name 'cs'.
My question is, how do I display the REFERER information in the repeater?
The code to parse the log file and bind it to the repeater is as follows:
string theDate =txtDate.Text;
string FILE_NAME = @"\\" +txtMachine.Text +
@"\C$\WINNT\System32\LogFiles\" +
drpSiteBox.SelectedItem.Text + @"\ex" + theDate + ".log";
FileStream fs = new FileStream(FILE_NAME, FileMode.Open,
FileAccess.Read,FileShare.ReadWrite);
StreamReader sr = new StreamReader(fs);
string strResult = sr.ReadToEnd();
sr.Close();
fs.Close();
sr=null;
fs=null;
string[] arLogLines = strResult.Split(Convert.ToChar("\n"));
dt = new DataTable("log");
string revisedColmNames=arLogLines[3].Replace("#Fields: ","");
string[] arColm=revisedColmNames.Split(Convert.ToChar(" "));
for(int j=0;j<arColm.Length;j++)
{
dt.Columns.Add(arColm[j]);
Debug.W开发者_运维百科riteLine(arColm[j]);
}
for (i =arLogLines.Length-1; i>3;i--)
{
// need this because some logs get additional data appended
// aren't unhandled exceptions great? The CLR just loves 'em...
try
{
dt.Rows.Add(arLogLines[i].Split(Convert.ToChar(" ")));
}
catch {}
}
DataGrid1.DataSource=dt;
DataGrid1.DataBind();
Note: this is the same code as in http://www.eggheadcafe.com/articles/20021203.asp
The problem here is to do with the way that the data binder operates over the data table and handles column/property names. Eval
uses reflection and the parentheses characters in the column names are causing this to fail (I need to jog my memory about how all this works again, it's been a while).
Just cast the underlying Container.DataItem
to the type that it is (a DataRowView
), then pick out the column:
<%# ((System.Data.DataRowView)Container.DataItem)["cs(Referer)"]%>
This is also faster because reflection isn't used which is slow.
Also I notice that you'd spelled 'Referer' incorrectly (you have two 'r's), so watch out for that as well.
To get this to work using Eval()
instead you need to do a bit more work. Change this:
for(int j=0;j<arColm.Length;j++)
{
dt.Columns.Add(arColm[j]);
Debug.WriteLine(arColm[j]);
}
To this:
for (int j = 0; j < arColm.Length; j++)
{
string colName = arColm[j].Replace("(", "_").Replace(")", "");
dt.Columns.Add(colName);
Debug.WriteLine(colName);
}
In the data binder Eval
expression change any column with parentheses in the name from:
Eval("cs(Referer)")
to:
Eval("cs_Referer")
But I'd go with the first method, it's less intrusive and much faster.
精彩评论