MVC has become the new hot thing that is being implemented in different programming languages. There are at least 20 MVC frameworks that I know of. Unlike my previous posts which were about CakePHP. This post is about my experience with ASP.NET MVC 2.
The story begins when I was debugging an application built with ASP.NET MVC 2 and I noticed that the object I am debugging nearly contains all the information in the database. I thought of implementing a nice sql dump of all the queries that are being executed with each request and print it to the page being rendered to for performance review - cheating the idea from CakePHP, I know!
After some searching, I found a great implementation of TextWriter that writes to the Debugger output window. However, lazy as I am, I do not want to switch from the browser window back to Visual studio then maximize the debugger window to see the queries. I just took the code that Kris Vandermotten wrote and made few modifications to it to output the queries to the web page in a div tag. You can set the div to be hidden if it is breaking the page layout.
using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Text;
namespace Nba.Models.DataRepository
{ /// <summary> /// Implements a <see cref="TextWriter"/> for writing information to the debugger log. /// </summary> /// <seealso cref="Debugger.Log"/>public class SqlDebuggerWriter : TextWriter
{private bool isOpen;
private static UnicodeEncoding encoding;
private readonly int level;
private readonly string category;
public static string SqlLog;
/// <summary> /// Initializes a new instance of the <see cref="DebuggerWriter"/> class. /// </summary>public SqlDebuggerWriter()
: this(0, Debugger.DefaultCategory)
{ } /// <summary> /// Initializes a new instance of the <see cref="DebuggerWriter"/> class with the specified level and category. /// </summary> /// <param name="level">A description of the importance of the messages.</param> /// <param name="category">The category of the messages.</param>public SqlDebuggerWriter(int level, string category)
: this(level, category, CultureInfo.CurrentCulture)
{ } /// <summary> /// Initializes a new instance of the <see cref="DebuggerWriter"/> class with the specified level, category and format provider. /// </summary> /// <param name="level">A description of the importance of the messages.</param> /// <param name="category">The category of the messages.</param> /// <param name="formatProvider">An <see cref="IFormatProvider"/> object that controls formatting.</param>public SqlDebuggerWriter(int level, string category, IFormatProvider formatProvider)
: base(formatProvider)
{this.level = level;
this.category = category;
this.isOpen = true;
}protected override void Dispose(bool disposing)
{isOpen = false;
base.Dispose(disposing);
}public override void Write(char value)
{if (!isOpen)
{throw new ObjectDisposedException(null);
}SqlLog += value.ToString();
Debugger.Log(level, category, value.ToString());
}public override void Write(string value)
{if (!isOpen)
{throw new ObjectDisposedException(null);
}if (value != null)
{SqlLog += value;
Debugger.Log(level, category, value);
} }public override void Write(char[] buffer, int index, int count)
{if (!isOpen)
{throw new ObjectDisposedException(null);
}if (buffer == null || index < 0 || count < 0 || buffer.Length - index < count)
{base.Write(buffer, index, count); // delegate throw exception to base class
}SqlLog += new string(buffer, index, count);
Debugger.Log(level, category, new string(buffer, index, count));
}public override Encoding Encoding
{get
{if (encoding == null)
{encoding = new UnicodeEncoding(false, false);
}return encoding;
} }public int Level
{get { return level; }
}public string Category
{get { return category; }
} }}Then the following lines:
In the model
db.Log = new Nba.Models.DataRepository.SqlDebuggerWriter();
In the controller
ViewData["SqlLog"] = SqlDebuggerWriter.SqlLog;
In the view
<div style="width:800px;display:none" >
<pre>
<%= ViewData["SqlLog"]%>
</pre>
</div>