I'm going to start a new project and gradually approaching the stage of writing some basic things. I decided to collect and systematize my knowledge about some aspects of software development on the ASP.Net platform, obtained for more than a year of commercial development. The result was this article. She does not pretend to fundamentally new things, everyone knows this for a long time, in a certain sense these are peculiar best practices. All that is written below is most likely useful for beginners, but experienced developers will be able to learn something interesting for themselves.
You and I live in a time of advanced development tools, debuggers that support debugging of multi-threaded applications, and many other extremely useful things. But like any other phenomenon, such progress has its drawbacks - on not the fastest machines, the step-by-step debugging process can turn into a developer’s nightmare. Everything hangs, the debugger hints to you that it would be time to upgrade the car, after a half-hour journey through the code of your offspring you press F10 again and with horror fly along with the exception thrown somewhere in the depths of the code to the top level, into a carefully crafted catch . The exception message tells you that incorrect arguments came to the method, but it is absolutely incomprehensible where they came from and how. Gritting your teeth and armed with patience, you once again start the hunt for a nasty bug ...
I have several years of programming programming competitions behind my back, which were accompanied by writing code on a variety of tools from Turbo Pascal to Visual Studio 2008 in a variety of conditions. Who does not know, Olympiads usually take place in various universities. Sometimes computers killed by students hung to impossibility, and the number of viruses on the machine exceeded any reasonable framework. However, all participants of the competition are in such conditions, so there is no time to complain - you need to solve the tasks. So, over the years I learned a very important thing: perhaps the best debagger is the console. Yes, yes, here is the same, the usual black thing, on which gray letters are crawling up. However, the colors depend on the user's imagination.
Even on fast machines, the console is convenient for debugging long iterative or recursive calculations — it gives out information much faster than a regular debugger, all at once, along with intermediate results, you just need to enter in the places of interest to you Console.WriteLine, printf, system.out.println or equivalent in the language in which you write your applications. The console is the same log, but you do not need to go into the files to view it, it is on your screen and you can see everything that interests you at once. In the end, I think that many of the developers used it at least once in their life for debugging.
Today I will show you, using the ASP.Net MVC application as an example, how to use the console when debugging and logging. So let's get started.
First, we need to unizalize the console itself. To do this, we describe a small static class ConsoleManager, in which we import AllocConsole from kernel32.dll. We will also add a method that will initialize the console, set its output and clean it before starting the application:
public static class ConsoleManager<br> {<br> [DllImport( "kernel32.dll" , EntryPoint = "AllocConsole" , CharSet = CharSet.Unicode)]<br> private static extern bool AllocConsole();<br><br> public static void InitializeConsoleManager()<br> {<br> #if CONSOLE<br> try <br> {<br> AllocConsole();<br> Console .SetOut( new TextWriter( new StreamWriter( Console .OpenStandardOutput(), Encoding .Default, 100)));<br> Console .Clear();<br> }<br> catch (Exception)<br> {<br> }<br> #endif <br> }<br> }<br> <br> * This source code was highlighted with Source Code Highlighter .
Since we do not want the console to be visible during normal operation of the application on the server, we enclosed the code initializing it in the conditional compilation directive and of course did not forget to define the CONSOLE symbol in the Debug configuration of the project. Now we climb into Global.asax and initialize the console at the start of the application:
protected void Application_Start()<br> {<br> ConsoleManager.InitializeConsoleManager();<br> // ... <br> }<br> <br> * This source code was highlighted with Source Code Highlighter .
Hooray, now when you start the application, we have a black application window! Great, but this work is not over - now we will decorate it a little. An almost indispensable attribute of any web application is the logs - because often they are practically the only evidence by which you can track down an error on a running server. Sin does not duplicate logger messages in our console - it saves a lot of time when debugging. In order to distinguish which messages need to be written to and to the file and to the console, and which only to the console we will describe the listing:
public enum Severity<br> {<br> None,<br> Event,<br> Error,<br> Debug,<br> }<br> <br> * This source code was highlighted with Source Code Highlighter .
It's simple:
- None - unimportant information, is not written to the file, is displayed on the console in dark gray in order not to distract; usage example - logging http-request;
- Event - an event in the life of the site - is written to a file, displayed on the console in green; example - user logged in;
- Error - somewhere there was a trouble - is written to a file, to the console in bright red; usage example - unhandled exception;
- Debug - almost the same as None, but more important - is displayed only on the console in blue; An example of use is the intermediate results of a long calculation that needs to be checked.
To determine the color corresponding to a specific type of message, we write a simple extension-method:
public static ConsoleColor GetLogEntryColor( this Severity severity)<br> {<br> switch (severity)<br> {<br> case Severity.None:<br> return ConsoleColor.DarkGray;<br> case Severity.Event:<br> return ConsoleColor.Green;<br> case Severity.Error:<br> return ConsoleColor.Red;<br> case Severity.Debug:<br> return ConsoleColor.Cyan;<br> default :<br> throw new ArgumentException( string .Format( "Unknown severity: '{0}'" , severity));<br> }<br> }<br> <br> * This source code was highlighted with Source Code Highlighter .
Here it should be noted that the declarative approach would be much more beautiful:
public enum Severity<br> {<br> [SeverityColor(ConsoleColor.DarkGray)]<br> None,<br> [SeverityColor(ConsoleColor.Green)]<br> Event,<br> [SeverityColor(ConsoleColor.Red)]<br> Error,<br> [SeverityColor(ConsoleColor.Cyan)]<br> Debug,<br> }<br> <br> * This source code was highlighted with Source Code Highlighter .
but for performance reasons, I refused it. The question is controversial and maybe in the future I will come back to it. Now all that remains is to describe our logger, not forgetting that ASP.Net applications are multi-threaded:
public static class Logger<br> {<br> [ThreadStatic]<br> private static Severity m_CurrentSeverity;<br><br> /// <summary> <br> /// Writes debug message to log <br> /// </summary> <br> public static void WriteToLog( string message)<br> {<br> WriteToLog(message, Severity.Debug);<br> }<br><br> public static void WriteToLog( string message, Severity severity)<br> {<br> lock ( typeof (Logger))<br> {<br> m_CurrentSeverity = severity;<br> WriteLineStart();<br> WriteLine(message);<br> }<br> }<br><br> private static void WriteLine( string message)<br> {<br> Write(message + Environment.NewLine);<br> }<br><br> private static void Write( string message, params object [] parameters)<br> {<br> Write( string .Format(message, parameters));<br> }<br><br> private static void Write( string message)<br> {<br> Console .ForegroundColor = m_CurrentSeverity.GetLogEntryColor();<br> Console .Write(message);<br> if (m_CurrentSeverity == Severity.Error || m_CurrentSeverity == Severity.Event)<br> {<br> // file logging <br> }<br> }<br><br> private static void WriteLineStart()<br> {<br> Write( "{0} -> " , DateTime .Now);<br> }<br> }<br> <br> * This source code was highlighted with Source Code Highlighter .
Everything is intentionally oversimplified for greater understanding. Console during debugging looks like this:

From my own experience I will say that with such a console the life of a developer becomes much easier.
Thank.
UPD. I was prompted here that there is an alternative tool - the
Debug View program, which implements almost identical functionality.