08 Apr 2008
This is a simple technique I use to log exceptions in all my web applications.
First lets start by adding the following to the web.config:
<appSettings>
<add key="LogUnhandledExceptions" value="true"/>
</appSettings>
Second, we add the following bit inside the Application_Error event of the Global.asax file. This will capture all the unhandled exceptions and log them into the database:
private static bool logUnhandledExceptions = Convert.ToBoolean(ConfigurationManager.AppSettings["LogUnhandledExceptions"]);
.
.
.
void Application_Error(object sender, EventArgs e)
{
if (logUnhandledExceptions)
{
if (Context != null)
{
if (Server.GetLastError() != null)
{
//Get reference to the source of the exception chain
Exception ex = Context.Server.GetLastError().GetBaseException();
YourCompany.Helpers.ExceptionHandler.Log(ex);
}
}
}
}
And now finally the main part. This is the class which will log all the relavent information related to the exception in the DB.
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Diagnostics;
using System.Data.SqlClient;
using System.Web.Configuration;
namespace YourCompany.Helpers
{
public static class ExceptionHandler
{
public static void Log(Exception ex)
{
if (ex.GetBaseException() != null)
{
try
{
HttpContext context = HttpContext.Current;
HttpBrowserCapabilities browser = context.Request.Browser;
string referer = String.Empty;
if (context.Request.UrlReferrer != null)
{
referer = context.Request.UrlReferrer.ToString();
}
using (SqlConnection sqlConnection = new SqlConnection(WebConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
{
using (SqlCommand sqlCommand = new SqlCommand())
{
sqlCommand.Connection = sqlConnection;
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlCommand.CommandText = "EventLog_Insert";
sqlCommand.Parameters.Add("@Source", SqlDbType.NVarChar).Value = ex.Source;
sqlCommand.Parameters.Add("@Message", SqlDbType.NVarChar).Value = ex.Message;
sqlCommand.Parameters.Add("@Form", SqlDbType.NVarChar).Value = context.Request.Form.ToString();
sqlCommand.Parameters.Add("@Path", SqlDbType.NVarChar).Value = context.Request.Path.ToString();
sqlCommand.Parameters.Add("@QueryString", SqlDbType.NVarChar).Value = context.Request.QueryString.ToString();
sqlCommand.Parameters.Add("@TargetSite", SqlDbType.NVarChar).Value = ex.TargetSite.ToString();
sqlCommand.Parameters.Add("@StackTrace", SqlDbType.NVarChar).Value = ex.StackTrace.ToString();
sqlCommand.Parameters.Add("@Referer", SqlDbType.NVarChar).Value = referer;
sqlCommand.Parameters.Add("@MachineName", SqlDbType.NVarChar).Value = context.Server.MachineName.ToString();
sqlCommand.Parameters.Add("@IPAddress", SqlDbType.NVarChar).Value = context.Request.UserHostAddress;
sqlCommand.Parameters.Add("@BrowserType", SqlDbType.NVarChar).Value = browser.Type;
sqlCommand.Parameters.Add("@BrowserName", SqlDbType.NVarChar).Value = browser.Browser;
sqlCommand.Parameters.Add("@BrowserVersion", SqlDbType.NVarChar).Value = browser.Version;
sqlCommand.Parameters.Add("@BrowserPlatform", SqlDbType.NVarChar).Value = browser.Platform;
sqlCommand.Parameters.Add("@SupportsCookies", SqlDbType.Bit).Value = browser.Cookies;
sqlCommand.Parameters.Add("@IsCrawler", SqlDbType.Bit).Value = browser.Crawler;
sqlConnection.Open();
sqlCommand.ExecuteNonQuery();
}
}
}
catch
{
// database error, not much you can do here except logging the error in the windows event log
EventLog.WriteEntry(ex.Source, "Database Error From Exception Handler!", EventLogEntryType.Error);
}
}
}
}
}
29 Mar 2008
Recently I was trying to write a little C# function for cropping images. I expected it to be a quick 5 minute task but I ended up spending a huge amount of time getting it to work correctly. I kept getting a very stubborn and mysterious error - “Invalid Parameter Used” - whenever I tried to save my newly cropped image by doing bitmap.Save(). I tried various suggestions I found on forums and blogs to no avail.
Finally I figured out what the problem was. I was encapulatning the Bitmap and Graphics objects inside a “using” statement. So the Bitmap object was being prematurely disposed before I returned it back to the caller.
So in the end my solution looked like this. I just god rid of the “usings”.
public Bitmap CropImage(Image image, Rectangle cropRect)
{
Bitmap bitmap = new Bitmap(cropRect.Width, cropRect.Height, PixelFormat.Format24bppRgb);
bitmap.SetResolution(image.HorizontalResolution, image.VerticalResolution);
Graphics graphics = Graphics.FromImage(bitmap);
graphics.DrawImage(image, 0, 0, cropRect, GraphicsUnit.Pixel);
return bitmap;
}
Usage -
Bitmap croppedBmp = CropImage(”~/uploads/test.jpg”, new Rectangle(x, y, width, height));
croppedBmp.Save();
Moral of the story: If you are getting this error while calling Bitmap.Save() then make sure you are not disposing your Bitmap object prematurely. Hope this helps.
12 Mar 2008
SharpZipLib is a great open source library for handeling all kinds of gzip/zip compression/decompression. More Info - http://www.icsharpcode.net/OpenSource/SharpZipLib/
In the following example I’m passing the HtmlInputFile object directly into the ZipInputStream to decompress the PostedFile and save its contents on the server.
.
.
using System.IO;
using ICSharpCode.SharpZipLib.Zip
.
.
private void UnzipAndSave(HtmlInputFile objFileUpload)
{
ZipInputStream s = new ZipInputStream(objFileUpload.PostedFile.InputStream);
ZipEntry theEntry;
string virtualPath = "~/uploads/";
string fileName = string.Empty;
string fileExtension = string.Empty;
string fileSize = string.Empty;
while ((theEntry = s.GetNextEntry()) != null)
{
fileName = Path.GetFileName(theEntry.Name);
fileExtension = Path.GetExtension(fileName);
if (!string.IsNullOrEmpty(fileName))
{
try
{
FileStream streamWriter = File.Create(Server.MapPath(virtualPath + fileName));
int size = 2048;
byte[] data = new byte[2048];
do
{
size = s.Read(data, 0, data.Length);
streamWriter.Write(data, 0, size);
} while (size > 0);
fileSize = Convert.ToDecimal(streamWriter.Length / 1024).ToString() + ” KB”;
streamWriter.Close();
//Add custom code here to add each file to the DB, etc.
}
catch (Exception ex)
{
Response.Write(ex.ToString());
}
}
}
s.Close();
}
12 Mar 2008
In this case I’m resizing the video and converting it to FLV format. For more ffmpeg commandline options - http://ffmpeg.mplayerhq.hu/ffmpeg-doc.html
private void ConvertVideo(string srcURL, string destURL)
{
string ffmpegURL = "~/project/tools/ffmpeg.exe";
DirectoryInfo directoryInfo = new DirectoryInfo(Path.GetDirectoryName(Server.MapPath(ffmpegURL)));
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = Server.MapPath(ffmpegURL);
startInfo.Arguments = string.Format("-i \"{0}\" -s 368x216 -aspect 1.7777 \"{1}\"", srcURL, destURL);
startInfo.WorkingDirectory = directoryInfo.FullName;
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardError = true;
using (Process process = new Process())
{
process.StartInfo = startInfo;
try
{
process.Start();
StreamReader standardOutput = process.StandardOutput;
StreamWriter standardInput = process.StandardInput;
StreamReader standardError = process.StandardError;
process.WaitForExit();
lblError.Text = standardError.ReadToEnd();
lblOutput.Text = standardOutput.ReadToEnd();
}
catch (Exception ex)
{
Response.Write(ex.ToString());
}
}
}
16 Feb 2008
Until recently I wasn’t entirely familiar with the concepts of Event Driven Programming, Event Bubbling, etc. Being a .NET developer I’ve been exposed to events and delegates but I never really understood the concept in its entirety. Somehow I had a hard time readily finding good sources online focusing on event driven programming especially using ASP.NET/C#. But I had to get myself more familiarized with the concept since I need to use a lot of that in my current project. So after doing some digging I found couple of good links which explain the concept quite well -
Hope that helps.