September 2009 - Posts
Hi
I come across number of posting at www.asp.net/forums for a exception handler that can handle exceptions and redirect the end user to custom errors page.
I have written below source code that catches un-recoverable exceptions and redirects the end user to custom errors page and emails the error stack to the configured email address. Note that it is quite configurable using web.config properties.
Note that below source is part of a Class Library project. It is quite feasible to use the source code in a class and modify web.config access properties to use it as you wish. You can call the methods in Applicaiton_Error() method in Global.asax file to get most out of it.
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.Configuration;
namespace WebUtils
{
/// <summary>
/// Appliction level exceptions are handled using this Class
/// </summary>
public class ExceptionHandler
{
public static string EmailAddress = WebConfigurationManager.
AppSettings["EmailAddress"];
/// <summary>
/// Application level unhandled exception stack trace is sent
///to the Email provided in web.config while redirecting the
///end user to GenericErrorPage.aspx
/// </summary>
/// <author>Raju Golla</author>
public static void ApplicationExceptionHandler()
{
//Get exception details
Exception ex = HttpContext.Current.Server.GetLastError();
if (ex is HttpUnhandledException && ex.InnerException != null)
{
ex = ex.InnerException;
}
if (ex != null)
{
try
{
//Email the error stack to the administrator/relevant developer
// const string EmailAddress = “informer@exception.com
///<mailto:“informer@exception.com>”;
//Create the mail message instanceSystem.Net.Mail.MailMessage
///mm = new System.Net.Mail.MailMessage(EmailAddress, EmailAddress);
//From||To
//Assign message properties
mm.Subject = WebConfigurationManager.AppSettings["EmailSubject"].ToString();
mm.Body = string.Format("An unhandled exception occurred:{0}Message:
{1}{0}{0} Stack Trace:{0}{2}", System.Environment.NewLine,
ex.Message, ex.StackTrace);
mm.IsBodyHtml = false;
//create SMTP client object
System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient();
//send the error stack mail message (uses web.config SMTP
/// settings section)
smtp.Send(mm);
}
//catch the Exception that is thrown when the SmtpClient is not able
///to complete a Send peration
catch(System.Net.Mail.SmtpException exc)
{
ErrorLog.LogException(exc);
}
//Redirect the user to CustomErrorPage.aspx
HttpContext.Current.Server.Transfer(WebConfigurationManager.
AppSettings["CustomErrorsPage"].ToString());
//("~/GenericErrorPage.aspx");
}
}
}
}
References:
http://www.4guysfromrolla.com/articles/091306-1.aspx
Here is the source code to encrypt and decrypt <connectionString> section in Web.config using RSA Protected Configuration provider model.
Note that below source code is from class library file. It is quite feasible to edit the code and use within a button click event as you wish.
Hope you find it useful!!
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
//specific to configuration
using System.Configuration;
using System.Web.Configuration;
using System.Web.Security;
namespace WebUtils
{
/// <summary>
/// Contains methods for Encrypting and decrypting connectionStrings
/// section in web.config
/// current encryption configuration model is Rsa,
/// it is feasible to change this to DataProtectionConfigurationProvider
/// </summary>
/// <author>Raju Golla</author>
public class EncryptDecrypt
{
//Get Application path using HttpContext
public static string path = HttpContext.Current.
Request.ApplicationPath;
/// <summary>
/// Encrypt web.config connectionStrings
/// section using Rsa protected configuration
/// provider model
/// </summary>
#region Encrypt method
public static void EncryptConnString()
{
Configuration config = WebConfigurationManager.
OpenWebConfiguration(path);
ConfigurationSection section =
config.GetSection("connectionStrings");
if (!section.SectionInformation.IsProtected)
{
section.SectionInformation.ProtectSection
("RsaProtectedConfigurationProvider");
config.Save();
}
}
#endregion
/// <summary>
/// Decrypts connectionStrings section in
///web.config using Rsa provider model
/// </summary>
#region Decrypt method
public static void DecryptConnString()
{
Configuration config = WebConfigurationManager.
OpenWebConfiguration(path);
ConfigurationSection section =
config.GetSection("connectionStrings");
if (section.SectionInformation.IsProtected)
{
section.SectionInformation.UnprotectSection();
config.Save();
}
}
#endregion
}
}
References:
http://www.beansoftware.com/ASP.NET-Tutorials/Encrypting-Connection-String.aspx
http://msdn.microsoft.com/en-us/library/ms998280.aspx
Response.Clear();
Response.Buffer = true;
Response.AddHeader("content-disposition", "attachment;filename=SearchResults.csv");
Response.Charset = "";
Response.ContentType = "application/text";
gvSearchResutls.AllowPaging = false;
//Bind DataTable to GridView
//Search() method returns a DataTable of search results
gvSearchResutls.DataSource = Search();
gvSearchResutls.DataBind();
//String builder class to add row data
StringBuilder sb = new StringBuilder();
for (int k = 0; k < gvSearchResutls.Columns.Count; k++)
{
//add separator
sb.Append(gvSearchResutls.Columns[k].HeaderText + ',');
}
append new line
sb.Append("\r\n");
Get Rows
for (int i = 0; i < gvSearchResutls.Rows.Count; i++)
{
//Get columns
for (int k = 0; k < gvSearchResutls.Columns.Count; k++)
{
//add separator
sb.Append(gvSearchResutls.Rows[i].Cells[k].Text + ',');
}
//append new line
sb.Append("\r\n");
}
Response.Output.Write(sb.ToString());
Response.Flush();
Response.End();
References:
http://www.aspsnippets.com/
http://www.victorchen.info/export-datatable-to-csv-file-download-in-c/
2: /// Export DataTable to CSV
4: /// <param name="searchResultsTable"></param>
5: /// <param name="filename"></param>
6: private void ExportsearchResultsTableToCSV(DataTable test, string filename)
9: //copy the structure of the data table
10: DataTable toExcel = test.Copy();
12: HttpContext context = HttpContext.Current;
14: //Loop through data table columns and output
15: foreach (DataColumn column in toExcel.Columns)
17: context.Response.Write(column.ColumnName + ",");
20: context.Response.Write(Environment.NewLine);
22: //Loop through rows and output
23: foreach (DataRow row in toExcel.Rows)
26: for (int i = 0; i < toExcel.Columns.Count; i++)
28: context.Response.Write(row[i].ToString().Replace(",", string.Empty) + ",");
32: context.Response.Write(Environment.NewLine);
36: //output the csv file
37: context.Response.ContentType = "text/csv";
38: context.Response.AppendHeader("Content-Disposition", "attachment; filename=" + filename + ".csv");
39: context.Response.End();
Here is the source code for downloading selected columns from DataTable to CSV file.
using System;
using System.IO;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
public partial class RecordDownLoad : System.Web.UI.Page
{
//Connection string for Test server
public string ConnectionString = ConfigurationManager.
ConnectionStrings
["MyConnectionString"].ToString();
protected void Page_Load(object sender, EventArgs e)
{
}
/// <summary>
/// Get data
/// </summary>
/// <returns>DataTable of records</returns>
private DataTable Search()
{
SqlConnection con = new SqlConnection(ConnectionString);
SqlCommand cmd = new SqlCommand("spSearchRecords", con);
cmd.CommandType = CommandType.StoredProcedure;
//Pass search criteria with parameters
cmd.Parameters.AddWithValue("@UserId",
Convert.ToString(Session["Id"]));
//Few more parameters from Session stored search criteria here
//Data adapter
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataTable dtResults = new DataTable();
DataSet ds = new DataSet();
//fill the data table with results
adapter.Fill(dtResults);
return dtResults;
}
/// <summary>
/// Process download as CSV
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void btnDownload_Click(object sender, EventArgs e)
{
Response.ContentType = "text/csv";
Response.AddHeader("Content-Disposition",
"Attachment;filename=Sample.csv");
//Get columns
foreach (ListItem li in chkList.Items)
{
if (li.Selected)
{
Response.Write(li.Text + ",");
}
}
Response.Write(Environment.NewLine);
DataTable dt = Search();
//Rows
foreach (DataRow row in dt.Rows)
{
foreach (ListItem li in chkList.Items)
{
if (li.Selected)
{
Response.Write(row[li.Value].ToString() + ",");
}
}
Response.Write(Environment.NewLine);
}
Response.End();
}
}
Hi
While working with DetailsView control I have come up with few resources when you want to perform update to the data within DetailsView using buttons out side of DetailsView control.
Here is the source code to update all the columns in DetailsView with edited data. Note that regard less of old values and new values database is updated with all the data in DetailsView(edited columns and non-edited columns).
//ASPX
<form id="form1" runat="server">
<div>
<asp:Button ID="btnEdit" runat="server" Text="Edit" onclick="btnEdit_Click" />
<asp:Button ID="btnUpdate" runat="server" Text="Update" onclick="btnUpdate_Click" />
<asp:Button ID="btnCancel" runat="server" Text="Cancel" onclick="btnCancel_Click" />
<br /><br />
<asp:DetailsView ID="DetailsView1" runat="server" Height="50px" Width="125px"
AutoGenerateRows="false" DataKeyNames="CustomerId"
onitemupdating="DetailsView1_ItemUpdating">
<Fields>
<asp:BoundField HeaderText="ID" DataField="CustomerId" />
<asp:BoundField HeaderText="Name" DataField="CustomerName" />
<asp:BoundField HeaderText="Deaprtment" DataField="Department" />
<asp:BoundField HeaderText="Address" DataField="address" />
<asp:BoundField HeaderText="Married" DataField="Married" />
<asp:BoundField HeaderText="Nationality" DataField="Nationality" />
</Fields>
</asp:DetailsView>
</div>
</form>
//code behind c#
using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class View : System.Web.UI.Page
{
public string conString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
protected void Page_Load(object sender, EventArgs e)
{
//Check if the page is the result of PostBack
if((!IsPostBack)
{
//Bind data
DetailsView1.DataSource = GetUser();
DetailsView1.DataBind();
}
}
/// <summary>
/// Get data
/// </summary>
/// <returns>DataTable with Customers data</returns>
private DataTable GetUser()
{
string custId = Request.QueryString["id"].ToString();
SqlConnection con = new SqlConnection(conString);
SqlCommand cmd = new SqlCommand("Select * From customer Where CustomerId= '" + custId + "' ", con);
cmd.CommandType = CommandType.Text;
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataTable CustomerTable = new DataTable();
adapter.Fill(CustomerTable);
return CustomerTable;
}
/// <summary>
/// Edit button click
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void btnEdit_Click(object sender, EventArgs e)
{
DetailsView1.ChangeMode(DetailsViewMode.Edit);
//Bind the DetailsView with data
DetailsView1.DataSource = GetUser();
DetailsView1.Databind();
}
/// <summary>
/// Cancel button click
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void btnCancel_Click(object sender, EventArgs e)
{
DetailsView1.ChangeMode(DetailsViewMode.ReadOnly);
//Change 3: Bind the DetailsView with custom method (i.e., GetUser())
DetailsView1.DataSource = GetUser();
DetailsView1.Databind();
}
/// <summary>
/// Update button click event
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void btnUpdate_Click(object sender, EventArgs e)
{
//http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.detailsview.updateitem.aspx
DetailsView1.UpdateItem(true);
}
/// <summary>
/// DetailsView updating event
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void DetailsView1_ItemUpdating(object sender, DetailsViewUpdateEventArgs e)
{
if(DetailsView1.CurrentMode == DetailsViewMode.Edit)
{
//Get DetailsView columns
TextBox txtUserName = DetailsView1.Rows[3].Cells[1].Controls[0] as TextBox;
//Note that you need FindControl for TemplateFields in DetailsView
TextBox txtUserID = DetailsView1.FindControl("txtUserID");
SqlConnection con = new SqlConnection((conString));
using (SqlCommand cmd = new SqlCommand("spUpdateUserRecord", Con))
{
//Specify the command type
cmd.CommandType = CommandType.StoredProcedure;
//Pass parameters
cmd.Parameters.AddWithValue("@UserName", txtUserName.Text.Trim());
cmd.Parameters.AddWithValue("@UserID", txtUserID.Text.Trim());
con.Open();
cmd.ExecuteNonQuery();
}
DetailsView1.ChangeMode(DetailsViewMode.ReadOnly);
//Change 4: Bind the DetailsView with custom method (i.e., GetUser())
DetailsView1.DataSource = GetUser();
DetailsView1.Databind();
}//end of if
}//end of Event
}
References
More Posts