Tuesday, May 8, 2012

.net Transaction

http://msdn.microsoft.com/en-us/library/ms971557.aspx

1.       Open the transaction using Connection.BeginTransaction().
2.       Enlist statements or stored procedure calls in the transaction by setting the Command.Transaction property of the Command objects associated with them.
3.       Depending on the provider, optionally use Transaction.Save() or Transaction.Begin() to create a savepoint or a nested transaction to enable a partial rollback.
4.       Commit or roll back the transaction using Transaction.Commit() or Transaction.Rollback().
public void SPTransaction(int partID, int numberMoved, int siteID)
{
   // Create and open the connection.
   SqlConnection conn = new SqlConnection();
   string connString = "connection string";
   conn.ConnectionString = connString;
   conn.Open();

   // Create the commands and related parameters.
   // cmdDebit debits inventory from the WarehouseInventory
   // table by calling the DebitWarehouseInventory stored procedure.
   SqlCommand cmdDebit = new SqlCommand("DebitWarehouseInventory", conn);
   cmdDebit.CommandType = CommandType.StoredProcedure;
   cmdDebit.Parameters.Add("@PartID", SqlDbType.Int, 0, "PartID");
   cmdDebit.Parameters["@PartID"].Direction =ParameterDirection.Input;
   cmdDebit.Parameters.Add("@Debit", SqlDbType.Int, 0, "Quantity");
   cmdDebit.Parameters["@Debit"].Direction = ParameterDirection.Input;

   // cmdCredit adds inventory to the SiteInventory
   // table by calling the CreditSiteInventory stored procedure.
   SqlCommand cmdCredit = new SqlCommand("CreditSiteInventory", conn);
   cmdCredit.CommandType = CommandType.StoredProcedure;
   cmdCredit.Parameters.Add("@PartID", SqlDbType.Int, 0, "PartID");
   cmdCredit.Parameters["@PartID"].Direction =ParameterDirection.Input;
   cmdCredit.Parameters.Add("@Credit", SqlDbType.Int, 0, "Quantity");
   cmdCredit.Parameters["@Credit"].Direction = ParameterDirection.Input;
   cmdCredit.Parameters.Add("@SiteID", SqlDbType.Int, 0, "SiteID");
   cmdCredit.Parameters["@SiteID"].Direction = ParameterDirection.Input;

   // Begin the transaction and enlist the commands.
   SqlTransaction tran = conn.BeginTransaction();
   cmdDebit.Transaction = tran;
   cmdCredit.Transaction  = tran;
   try
   {
      // Execute the commands.
      cmdDebit.Parameters["@PartID"].Value = partID;
      cmdDebit.Parameters["@Debit"].Value = numberMoved;
      cmdDebit.ExecuteNonQuery();
      cmdCredit.Parameters["@PartID"].Value = partID;
      cmdCredit.Parameters["@Credit"].Value = numberMoved;
      cmdCredit.Parameters["@SiteID"].Value = siteID;
      cmdCredit.ExecuteNonQuery();
      // Commit the transaction.
      tran.Commit();
   }
   catch(SqlException ex)
   {
      tran.Rollback();
      // Additional error handling if needed.
   }
   finally
   {      conn.Close();   }}

Using Transactions with a DataAdapter

public void CBTransaction()
{
   // Create and open the connection.
   SqlConnection conn = new SqlConnection();
   string connString = "...";
   conn.ConnectionString = connString;
   conn.Open();
        
   // Create the DataAdapters.
   string cmdString = "Select WIID, PartID, Quantity from WarehouseInventory";
   SqlDataAdapter daWarehouse =  new SqlDataAdapter(cmdString,conn);
   cmdString = "Select SiteID, PartID, Quantity from SiteInventory";
   SqlDataAdapter daSite = new SqlDataAdapter(cmdString,conn);

   // Create the DataSet.
   DataSet ds = new DataSet();

   // Create the CommandBuilders and generate
   // the INSERT/UPDATE/DELETE commands.
   SqlCommandBuilder cbWarehouse = new SqlCommandBuilder(daWarehouse);
   SqlCommand warehouseDelete = cbWarehouse.GetDeleteCommand();
   SqlCommand warehouseInsert = cbWarehouse.GetInsertCommand();
   SqlCommand warehouseUpdate = cbWarehouse.GetUpdateCommand();

   SqlCommandBuilder cbSite = new SqlCommandBuilder(daSite);
   SqlCommand siteDelete = cbSite.GetDeleteCommand();
   SqlCommand siteInsert = cbSite.GetInsertCommand();
   SqlCommand siteUpdate = cbSite.GetUpdateCommand();

   // Fill the DataSet.
   daWarehouse.Fill(ds, "WarehouseInventory");
   daSite.Fill(ds, "SiteInventory");

   // Begin the transaction and enlist the commands.
   SqlTransaction tran = conn.BeginTransaction();
   warehouseDelete.Transaction = tran;
   warehouseInsert.Transaction = tran;
   warehouseUpdate.Transaction = tran;
   siteDelete.Transaction = tran;
   siteInsert.Transaction = tran;
   siteUpdate.Transaction = tran;

   // Modify data to move inventory from WarehouseInventory to SiteInventory.           
   try
   {
      //Execute the commands
      daWarehouse.Update(ds, "WarehouseInventory");
      daSite.Update(ds, "SiteInventory");
      //Commit the transaction
      tran.Commit();
   }
   catch(SqlException ex)
   {
      //Roll back the transaction.
      tran.Rollback();
      //Additional error handling if needed.
   }
   finally
   {           conn.Close();   }}

Using Savepoints


public void SavepointTransaction()
{
   // Create and open the connection.
   SqlConnection conn = new SqlConnection();
   string connString = ". . .";
   conn.ConnectionString = connString;
   conn.Open();

   // Create the commands.
   // cmdInsertCustomer creates a new customer record  by calling the DebitWarehouseInventory
      SqlCommand cmdInsertCustomer =       new SqlCommand("CreateCustomer", conn);
   cmdInsertCustomer.CommandType = CommandType.StoredProcedure;
   cmdInsertCustomer.Parameters.Add ("@FirstName", SqlDbType.NVarChar, 50, "FirstName");
   cmdInsertCustomer.Parameters.Add ("@LastName", SqlDbType.NVarChar, 50, "LastName");
   cmdInsertCustomer.Parameters.Add ("@Email", SqlDbType.NVarChar, 50, "Email");
   cmdInsertCustomer.Parameters.Add("@CID", SqlDbType.Int, 0);
   cmdInsertCustomer.Parameters["@FirstName"].Direction = ParameterDirection.Input;
   cmdInsertCustomer.Parameters["@LastName"].Direction =  ParameterDirection.Input;
   cmdInsertCustomer.Parameters["@Email"].Direction = ParameterDirection.Input;
   cmdInsertCustomer.Parameters["@CID"].Direction =  ParameterDirection.Output;

   // cmdRequestMaterials creates a pick list of the materials requested by the customer
   // by calling the InsertMaterialsRequest stored procedure.
   SqlCommand cmdRequestMaterials =  new SqlCommand("InsertMaterialsRequest", conn);
   cmdRequestMaterials.CommandType = CommandType.StoredProcedure;
   cmdRequestMaterials.Parameters.Add ("@CustomerID", SqlDbType.Int, 0, "CustomerId");
   cmdRequestMaterials.Parameters.Add ("@RequestPartID", SqlDbType.Int, 0, "PartId");
   cmdRequestMaterials.Parameters.Add ("@Number", SqlDbType.Int, 0, "NumberRequested");
   cmdRequestMaterials.Parameters["@CustomerID"].Direction = ParameterDirection.Input;
   cmdRequestMaterials.Parameters["@RequestPartID"].Direction = ParameterDirection.Input;
   cmdRequestMaterials.Parameters["@Number"].Direction = ParameterDirection.Input;

   // cmdUpdateSite debits the requested materials from the inventory of those available by calling the UpdateSiteInventory stored procedure.
   SqlCommand cmdUpdateSite = new SqlCommand("UpdateSiteInventory", conn);
   cmdUpdateSite.CommandType = CommandType.StoredProcedure;
   cmdUpdateSite.Parameters.Add("@SiteID", SqlDbType.Int, 0, "SiteID");
   cmdUpdateSite.Parameters.Add("@SitePartID", SqlDbType.Int, 0, "PartId");
   cmdUpdateSite.Parameters.Add("@Debit", SqlDbType.Int, 0, "Debit");
   cmdUpdateSite.Parameters["@SiteID"].Direction =  ParameterDirection.Input;
   cmdUpdateSite.Parameters["@SitePartID"].Direction = ParameterDirection.Input;
   cmdUpdateSite.Parameters["@Debit"].Direction = ParameterDirection.Input;
        
   // Begin the transaction and enlist the commands.
   SqlTransaction tran = conn.BeginTransaction();
   cmdInsertCustomer.Transaction = tran;
   cmdUpdateSite.Transaction  = tran;
   cmdRequestMaterials.Transaction  = tran;
   try
   {
      // Execute the commands.
      cmdInsertCustomer.Parameters["@FirstName"].Value = "Mads";
      cmdInsertCustomer.Parameters["@LastName"].Value= "Nygaard";
      cmdInsertCustomer.Parameters["@Email"].Value = "MadsN@AdventureWorks.com";
      cmdInsertCustomer.ExecuteNonQuery();
      tran.Save("Customer");
      cmdRequestMaterials.Parameters["@CustomerID"].Value = cmdInsertCustomer.Parameters["@CID"].Value;
      cmdRequestMaterials.Parameters["@RequestPartID"].Value = 3;
      cmdRequestMaterials.Parameters["@Number"].Value= 22;
      cmdRequestMaterials.ExecuteNonQuery();

      cmdUpdateSite.Parameters["@SitePartID"].Value= 3;
      cmdUpdateSite.Parameters["@Debit"].Value = 22;
      cmdUpdateSite.Parameters["@SiteID"].Value = 4;
      cmdUpdateSite.ExecuteNonQuery();

      // Commit the transaction.
      tran.Commit();
   }
   catch(SqlException sqlEx)
   {
      try
      {
         // Roll back the transaction to the savepoint.
         Console.WriteLine(sqlEx.Message);
         tran.Rollback("Customer");
         tran.Commit();
         // Add code to notify user or otherwise handle   the fact that the procedure was only
         // partially successful.
      }
      catch(SqlException ex)
      {
         // If the partial rollback fails, roll back the whole transaction.
         Console.WriteLine(ex.Message);
         tran.Rollback();
         // Additional error handling if needed.
      }
   }
   finally
   {           conn.Close();   }}

Using Nested Transactions

public void NestedTransaction(string UID, string pwd)
{
   // Create and open the connection.
   OleDbConnection conn = new OleDbConnection();
   StringBuilder sb = new StringBuilder();
   sb.Append("Jet OLEDB:System database=");
   sb.Append(@"C:\Databases\system.mdw;");
   sb.Append(@"Data Source=C:\Databases\orders.mdb;");
   sb.Append("Provider=Microsoft.Jet.OLEDB.4.0;");
   sb.Append("User ID=" + UID + ";Password=" + pwd);
   string connString = sb.ToString();
   conn.ConnectionString = connString;
   conn.Open();

   // Create the commands.
   string cmdString = "Insert into Orders"
      + " (OrderID, OrderDate, CustomerID)"
      + " values('ABC60', #4/14/04#, 456)";
   OleDbCommand cmdInsertOrder = new OleDbCommand(cmdString,conn);

   //No need to insert OrderLineID, as that is an AutoNumber field.
   cmdString = "Insert into OrderLines (OrderID, PartID, Quantity)"
      + " values('ABC60', 25, 10)";
   OleDbCommand cmdInsertOrderLine = new OleDbCommand(cmdString,conn);
   cmdString = "Insert into PickList (OrderID, PartID, Quantity) values('ABC60', 25, 10)";
   OleDbCommand cmdCreatePickList = new OleDbCommand(cmdString,conn);

   // Begin the outer transaction and enlist the order-related commands.
   OleDbTransaction tran = conn.BeginTransaction();
   cmdInsertOrder.Transaction = tran;
   cmdInsertOrderLine.Transaction = tran;
           
   try
   {
      // Execute the commands   to create the order and order line items.
      cmdInsertOrder.ExecuteNonQuery();
      cmdInsertOrderLine.ExecuteNonQuery();
      // Create a nested transaction that allows the pick list creation to succeed or fail
      // separately if necessary.
      OleDbTransaction nestedTran = tran.Begin();           
      // Enlist the pick list command.
      cmdCreatePickList.Transaction = nestedTran;
      try
      {
         // Execute the pick list command.
         cmdCreatePickList.ExecuteNonQuery();
         // Commit the nested transaction.
         nestedTran.Commit();
      }
      catch(OleDbException ex)
      {
         //Roll back the transaction.
         nestedTran.Rollback();
         // Add code to notify user or otherwise handle the fact that the procedure was only
         // partially successful.
      }
      // Commit the outer transaction.
      tran.Commit();
   }
   catch(OleDbException ex)
   {
      //Roll back the transaction.
      tran.Rollback();
      //Additional error handling if needed.
   }
   finally
   { conn.Close();  }}
http://www.roque-patrick.com/windows/final/bbl0201.html

DataSet ds = new DataSet();
SqlConnection cn = new SqlConnection(
ConfigurationSettings.AppSettings("ConnectString"));SqlCommand cmd = new SqlCommand("usp_FillTransactions", cn);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataAdapter daTransactions = new SqlDataAdapter(cmd);
daTransactions.Fill(ds, "Transactions");  

//pass in ds as DataSet, and "Transactions" as the table name
SqlCommand cmdDetails = new SqlCommand("usp_FillTransactionDetails", cn);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataAdapter daTransactionDetails = new SqlDataAdapter(cmdDetails);
daTransactionDetails.Fill(ds, "Details");



DataRelation Tran_Detail =
new DataRelation("ds", ds.Tables[0].Columns["TransID"], ds.Tables[1].Columns["TransID"]);
//For the sake of brevity I'm not going to translate each of the above, but you can switch between the nominal or the ordinal and provided
//you use the correct index, it will work the same
ds.Relations.Add(Tran_Detail);

Like I said, this is the simplest of the constructors. The other overloads are provided below:

DataRelation(string, ParentDataColum(), ChildDataColumn())  

'this takes an array of DataColumns, so you could use this constructor the same way we did above

DataRelation(string, ParentDataColumn, ChildDataColumn, Boolean)

//Where the boolean instructs the DataRelation whether or not to enforce the constraints.  For good reason Constraints are enabled by default, and I'd recommend against setting this to false unless you have a really good reason to do so...and if you do, don't complain to me when a user does something you didn't intend and your validation code misses it.Similarly, there is an Array Based constructor with the Boolean:

DataRelations(string, ParentDataColumn(), ChildDataColumn(), Boolean)
//this is identical to the one above it except it allows the use of multiple columns aka Composite Keys
The final constructor allows you to simply name the tables and the columns, but this will already be done most of the time.  For that reason, I'm not going to address, but it's Here if you find the need to use it.

 
DataColumn[] TransactionColumns;
DataColumn[] DetailColumns;

TransactionColumns = new DataColumn[] {ds.Tables[0].Columns["TransID"], ds.Table[0].Columns["CustomerID"], ds.Tables[0].Columns["SalePersonID"]};
DetailColumns = new DataColumn[] {ds.Tables[1].Columns["TransID"], ds.Table[1].Columns["CustomerID"], ds.Tables[1].Columns["SalePersonID"]};

DataRelation Tran_Detail = new DataRelation("myDataRelation", TransactionColumns, DetailColumns);
ds.Relations.Add(Tran_Detail);




*********
{
    // Create a Projects list    ProjectList projects = new ProjectList();

    // Set SQL query to fetch projects    string sqlQuery =
      "Select * from Projects; Select * from Steps";

    // Create dataset    DataSet dataSet = new DataSet();

    // Populate dataset    using (SqlConnection connection =
           new SqlConnection(m_ConnectionString))
    {
        SqlCommand command = new SqlCommand(sqlQuery, connection); SqlDataAdapter dataAdapter = new SqlDataAdapter(command);
        dataAdapter.Fill(dataSet);
    }

    // Set dataset table names    dataSet.Tables[0].TableName = "Projects";
    dataSet.Tables[1].TableName = "Steps";

    // Create a data relation between projects    // (parents) and steps (children)    DataColumn parentColumn =
       dataSet.Tables["Projects"].Columns["ProjectID"];
    DataColumn childColumn =
       dataSet.Tables["Steps"].Columns["ProjectID"];
    DataRelation projectsToSteps =
       new DataRelation("ProjectsToSteps",
       parentColumn, childColumn);
    dataSet.Relations.Add(projectsToSteps);

    // Create a Projects collection from the data set    ProjectList projectList = new ProjectList();
    ProjectItem nextProject = null;
    StepItem nextStep = null;
    foreach (DataRow parentRow in dataSet.Tables["Projects"].Rows)
    {
        // Create new project         nextProject = new ProjectItem();

        // Fill in its properties        nextProject.ID = Convert.ToInt32(parentRow["ProjectID"]);
        nextProject.Name = parentRow["Name"].ToString();

        /* Read in other fields from the record... */

        // Get its steps        DataRow[] childRows =
          parentRow.GetChildRows(dataSet.Relations["ProjectsToSteps"]);

        // Create StepItem objects for each of its steps        foreach (DataRow childRow in childRows)
        {
            // Create new step            nextStep = new StepItem();

            // Fill in its properties            nextStep.ID = Convert.ToInt32(childRow["StepID"]);
            nextStep.Date = Convert.ToDateTime(childRow["Date"]);
            nextStep.Description = childRow["Description"].ToString();

            // Add new step to the project            nextProject.Steps.Add(nextStep);
        }

        // Add new project to the Projects list        projectList.Add(nextProject);
    }

    // Dispose of the DataSet    dataSet.Dispose();

    // Set return value    return projectList;
}


****
parent and child table relation
public void LoadAuthorList(AuthorList authorList)
{
    // Build query to get authors and their books    StringBuilder sqlQuery = new StringBuilder();
    sqlQuery.Append("Select AuthorID, LastName," +
                    " FirstName, SSNumber From Authors; ");
    sqlQuery.Append("Select BookID, SkuNumber," +
                    " AuthorID, Title, Price From Books");

    // Get a data set from the query    DataSet dataSet =
      DataProvider.GetDataSet(sqlQuery.ToString());

    // Create variables for data set tables    DataTable authorsTable = dataSet.Tables[0];
    DataTable booksTable = dataSet.Tables[1];

    // Create a data relation from Authors    // (parent table) to Books (child table)    DataColumn parentColumn = authorsTable.Columns["AuthorID"];
    DataColumn childColumn = booksTable.Columns["AuthorID"];
    DataRelation authorsToBooks = new
      DataRelation("AuthorsToBooks", parentColumn, childColumn);
    dataSet.Relations.Add(authorsToBooks);

    // Load our AuthorList from the data set    AuthorItem nextAuthor = null;
    BookItem nextBook = null;
    foreach (DataRow parentRow in authorsTable.Rows)
    {
        // Create a new author        bool dontCreateDatabaseRecord = false;
        nextAuthor = new AuthorItem(dontCreateDatabaseRecord);

        // Fill in author properties        nextAuthor.ID = Convert.ToInt32(parentRow["AuthorID"]);
        nextAuthor.FirstName = parentRow["FirstName"].ToString();
        nextAuthor.LastName = parentRow["LastName"].ToString();
        nextAuthor.LastName = parentRow["LastName"].ToString();
        nextAuthor.SSNumber = parentRow["SSNumber"].ToString();

        // Get author's books        DataRow[] childRows = parentRow.GetChildRows(authorsToBooks);

        // Create BookItem object for each of the authors books        foreach (DataRow childRow in childRows)
        {
            // Create a new book            nextBook = new BookItem();

            // Fill in book's properties            nextBook.ID = Convert.ToInt32(childRow["BookID"]);
            nextBook.SkuNumber = childRow["SkuNumber"].ToString();
            nextBook.Title = childRow["Title"].ToString();
            nextBook.Price = Convert.ToDecimal(childRow["Price"]);

            // Add the book to the author            nextAuthor.Books.Add(nextBook);
        }

        // Add the author to the author list        authorList.Add(nextAuthor);
    }

    // Dispose of the data set    dataSet.Dispose();
}

transaction

1.example 1

SqlTransaction tn ;  //declare a transaction
const string sql = "INSERT INTO Employees1(EmpID) VALUES (@UserID)";SqlConnection cn = new SqlConnection
("data source=AUG-SQLSRV;initialcatalog=HumanResources;integrated security=SSPI");try{if(cn.State != ConnectionState.Open){cn.Open();}}
//If we throw an exception on Open, which is a 'risky' operation
//manually make the assertino fail by setting it to false and use
  //ex.ToString() to get the information about the exception.
catch (SqlException ex){Debug.Assert(false, ex.ToString());}//Instantiate command with CommandText and Connection and t      
//transaction  
    tn = cn.BeginTransaction();
    SqlCommand cmd = new SqlCommand(sql, cn,tn);
    cmd.Parameters.Clear();
    cmd.Parameters.Add("@UserID", SqlDbType.Int).Value = 314;
  
try  {       
  
//You can test for records affected, in this case we know it   
  //would be at most one record.    
   int i = cmd.ExecuteNonQuery();
  
//If successful, commit the transaction 

  //Loop 5 times and just add the id's incremented each time    
   for(int x=0; x<5; x++)<BR>       
    {
          cmd.Parameters["@UserID"].Value = (315 + x);
          cmd.ExecuteNonQuery();
      }
       cmd.Parameters["@UserID"].Value = (325);
       cmd.ExecuteNonQuery();
       tn.Commit();
   }
      
catch
(SqlException ex)
{
          Debug.Assert(
false, ex.ToString());

//If it failed for whatever reason, rollback the
//transaction        
tn.Rollback();
//No need to throw because we are at a top level call and
//nothing is handling exceptions     }
      
finally
{
        
//Check for close and respond accordingly        

        if(cn.State != ConnectionState.Closed){cn.Close();}
        
//Clean up my mess
        
          cn.Dispose();
          cmd.Dispose();
          tn.Dispose();
     }



2.Example 2

 private static void Demo1()
   {
      SqlConnection db = new SqlConnection("connstringhere");
      SqlTransaction transaction;

      db.Open();
      transaction = db.BeginTransaction();
      try
      {
         new SqlCommand("INSERT INTO TransactionDemo (Text) VALUES ('Row1');", db, transaction)
            .ExecuteNonQuery();
         new SqlCommand("INSERT INTO TransactionDemo (Text) VALUES ('Row2');", db, transaction)
            .ExecuteNonQuery();
         new SqlCommand("INSERT INTO CrashMeNow VALUES ('Die', 'Die', 'Die');", db, transaction)
            .ExecuteNonQuery();
         transaction.Commit();
      }
      catch (SqlException sqlError)
      {
         transaction.Rollback();
      }
      db.Close();
   }

3.Example 3

SqlConnection myConnection = new SqlConnection("...");
myConnection.Open();

// Start a local transaction.
SqlTransaction myTrans = myConnection.BeginTransaction();
SqlCommand myCommand = myConnection.CreateCommand();
myCommand.Transaction = myTrans;

try
{
  myCommand.CommandText = "Insert into Region (RegionID, RegionDescription) VALUES (100, 'Description')";
  myCommand.ExecuteNonQuery();
  myCommand.CommandText = "Insert into Region (RegionID, RegionDescription) VALUES (101, 'Description')";
  myCommand.ExecuteNonQuery();
  myTrans.Commit();
  Console.WriteLine("Both records are written to database.");
}
catch(Exception e)
{
  try
  {
    myTrans.Rollback();
  }
  catch (SqlException ex)
  {
    if (myTrans.Connection != null)
    {
      Console.WriteLine("An exception of type " + ex.GetType() +
                        " was encountered while attempting to roll back the transaction.");
    }
  }

  Console.WriteLine("An exception of type " + e.GetType() +
                    "was encountered while inserting the data.");
  Console.WriteLine("Neither record was written to database.");
}
finally
{
  myConnection.Close();
}

Global Exception handler

1.Apart from being a terrible user experience unhandled exceptions can also be a security problem. 
implement a global exception handler.To do this, open the Global.asax file
Add code to implement the Application_Error handler as follows.
void Application_Error(object sender, EventArgs e)
     
{
     
Exception myEx =  Server.GetLastError();
   
String RedirectUrlString = "~/Error.aspx?InnerErr=" +
           myEx
.InnerException.Message.ToString() + "&Err=" + myEx.Message.ToString();
     
Response.Redirect(RedirectUrlString);
     
}

2.Then add a page named Error.aspx to the solution and add this markup snippet.
<center>
 
<div class="ContentHead">ERROR</div><br /><br />
 
<asp:Label ID="Label_ErrorFrom" runat="server" Text="Label"></asp:Label><br /><br />
 
<asp:Label ID="Label_ErrorMessage" runat="server" Text="Label"></asp:Label><br /><br /> </center>


3.Now in the Page_Load event handler extract the error messages from the Request Object.
protected void Page_Load(object sender, EventArgs e) {
   
Label_ErrorFrom.Text = Request["Err"].ToString();
   
Label_ErrorMessage.Text = Request["InnerErr"].ToString(); }