Tuesday, May 24, 2011

Ajax ScriptManager

The ASP .NET ScriptManager manages ASP.NET Ajax script libraries and script files, partial-page rendering, and client proxy class generation for Web and application services. Here are some tips for the ScriptManager that I have found useful.
Please note that many of these topics apply to ASP .NET 4.0.

Access ScriptManager From Child
You can only have one instance of the ScriptManager per page, so a common practice for a web form application that uses Master Pages is to put that reference in the master page. To access this instance from the child page, you must call the GetCurrent static method and pass in a reference to the page.

ScriptManager sm = ScriptManager.GetCurrent(this);

Access ScriptManager From UserControl
From a user control, you do the same thing, but this time the page reference comes from the Control.Page property.

ScriptManager sm = ScriptManager.GetCurrent(this.Page);

Register Async PostBack Control
To register a control as a trigger for asynchronous postbacks from code, you must first obtain the reference to the ScriptManager, and then call the RegisterAsyncPostBackControl method, passing in your control.

ScriptManager sm = ScriptManager.GetCurrent(this);
sm.RegisterAsyncPostBackControl(btnSave);

ScriptMode Property
The ScriptMode property controls whether debug or release versions of the script libraries are rendered to the browser. You should ONLY use the debug mode in development, as the debug libraries are much larger than the release versions. If no script mode is specified, then debug mode will be used when the retail attribute of the deployment configuration element is set to false. Since this setting cannot be set at the application level (machine level only), setting the script mode to release for deployment is recommended.

asp:ScriptManager ID="SM1" runat="server" ScriptMode="Release"

EnableCdn Property
The EnableCdn property allows you to specify whether the script libraries are loaded from Microsoft’s Content Delivery Network (CDN) or not. Using the CDN is recommended, as it will load the most up to date script libraries from cache servers located around the world, which can significantly improve your website’s performance, and ensure that you are always using the latest libraries.

asp:ScriptManager ID="SM1" runat="server" EnableCdn="true"

Thursday, May 19, 2011

When you work with master pages and content pages, both can use the same events (such as Page_Load).Be sure you know which events come before others. You are bringing two classes together to create a singlepage class, and a specific order is required. When an end user requests a content page in the browser, the event ordering is as follows:

Master page child controls initialization:
All server controls contained within the master page are first initialized.
Content page child controls initialization: All server controls contained in the content page are initialized.
Master page initialization: The master page itself is initialized.
Content page initialization: The content page is initialized.
Content page load: The content page is loaded (this is the Page_Load event followed by the Page_LoadComplete event).
Master page load: The master page is loaded (this is also the Page_Load event).
Master page child controls load: The server controls on the master page are loaded onto the page.
Content page child controls load: The server controls on the content page are loaded onto the page.


How to access master page controls from content pages

Label headerLabel = (Label)
Master.FindControl("Header"); // Header is my master page label id.
headerLabel.Text = "This label content is set through the Page_Load event of the child page";

The following is the sequence in which events occur when a master page is merged with a content page:

1.Master page controls Init event.

2.Content controls Init event.

3.Master page Init event.

4.Content page Init event.

5.Content page Load event.

6.Master page Load event.

7.Content controls Load event.

8.Content page PreRender event.

9.Master page PreRender event.

10.Master page controls PreRender event.

11.Content controls PreRender event.

Friday, May 6, 2011

How to call Server Side function from Client Side Code using PageMethods in ASP.NET AJAX

You cannot call server-side code ‘directly’ from client-side code. That is because by design, the server side code executes at server side and client side code at the client. However there are some workarounds. To call serverside code from javascript, you will need to use AJAX, and the easiest way out, is to use the ASP.NET AJAX Extensions.
One option while using Microsoft ASP.NET AJAX is to call ASP.NET Web services (.asmx files) from the browser by using client script. The script can call a webservice containing server-based methods (Web methods) and invoke these methods without a postback and without refreshing the whole page. However this approach could be overkill sometimes, to perform the simplest of tasks. Moreover the logic needs to be kept in a separate .asmx file. We need something that is more ‘integrated’ with our solution.
The option we are going to use in this article involves PageMethods. A PageMethod is basically a public static method that is exposed in the code-behind of an aspx page and is callable from the client script. PageMethods are annotated with the [WebMethod] attribute. The page methods are rendered as inline JavaScript.
Let us explore PageMethods with an example. The example we will be discussing here may not be the best example to explain PageMethods, but it will give you an idea of how to call server side code from client side. In this example, we will be connecting to the Customers table in the Northwind database. We will have some textboxes which will accept the CustomerID and in turn return the Contact Name of that Customer. The method returning ContactName will be called whenever the textbox loses focus. We will be using the onblur event where a javascript code will take in the value(CustomerID) from the textbox. This javascript function will then call a PageMethod (server side code) which returns the ContactName without any page refresh.
I assume that you have downloaded and installed ASP.NET AJAX extensions for ASP.NET 2.0. If not, I would advise you to download the extensions from here and install it before moving ahead. At any point of time, if you find a difficulty in understanding the code, download the sample project attached with this article at the end.
Step 1: Create an ASP.NET AJAX enabled website. Go to File > New > Website > ASP.NET AJAX-Enabled Web Site. Give the solution a name and location and click Ok.
Step 2: Drag and drop 2 labels and 4 textbox controls. We will be accepting the CustomerID from the user in the 2 textboxes and displaying the ‘ContactName’ in the other two textboxes. The textboxes that will display ‘ContactName’ has some properties set that will make it appear as a label without a border. Just set the BorderStyle=None, BorderColor=Transparent and ReadOnly=True. The markup will look similar to the following:
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server"/>
<div>
<asp:Label ID="lblCustId1" runat="server" Text="Customer ID 1">asp:Label>
<asp:TextBox ID="txtId1" runat="server">asp:TextBox><br />
<asp:TextBox ID="txtContact1" runat="server" BorderColor="Transparent" BorderStyle="None"
ReadOnly="True">asp:TextBox><br />
<br />
<asp:Label ID="lblCustId2" runat="server" Text="Customer ID 2">asp:Label>
<asp:TextBox ID="txtId2" runat="server">asp:TextBox><br />
<asp:TextBox ID="txtContact2" runat="server" BorderColor="Transparent" BorderStyle="None"
ReadOnly="True">asp:TextBox> <br />
div>
form>
Before moving ahead, we will store our connection string information in the Web.config. Add the following tag below your configSections> tag. Remember we have created an ‘ASP.NET AJAX enabled website’. The tag configSections> along with some other tags automatically get added to the web.config.
<connectionStrings>
<removename="all"/>
<addname="NorthwindConnectionString"connectionString="Data Source=(local); Initial Catalog=Northwind; Integrated Security = SSPI;"/>
connectionStrings>
Step 3: Currently we will add a method, ‘GetContactName()’ which will accept a CustomerID and return the Contact Name information from the Northwind database, Customer table. We will then transform this method as a PageMethod.
C#
public static string GetContactName(string custid)
{
if (custid == null || custid.Length == 0)
return String.Empty;
SqlConnection conn = null;
try
{
string connection = ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString;
conn = new SqlConnection(connection);
string sql = "Select ContactName from Customers where CustomerId = @CustID";
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.AddWithValue("CustID", custid);
conn.Open();
string contNm = Convert.ToString(cmd.ExecuteScalar());
return contNm;
}
catch (SqlException ex)
{
return "error";
}
finally
{
conn.Close();
}
}
VB.NET
Public Shared Function GetContactName(ByVal custid As String) As String
If custid Is Nothing OrElse custid.Length = 0 Then
Return String.Empty
End If
Dim conn As SqlConnection = Nothing
Try
Dim connection As String = ConfigurationManager.ConnectionStrings("NorthwindConnectionString").ConnectionString
conn = New SqlConnection(connection)
Dim sql As String = "Select ContactName from Customers where CustomerId = @CustID"
Dim cmd As SqlCommand = New SqlCommand(sql, conn)
cmd.Parameters.AddWithValue("CustID", custid)
conn.Open()
Dim contNm As String = Convert.ToString(cmd.ExecuteScalar())
Return contNm
Catch ex As SqlException
Return "error"
Finally
conn.Close()
End Try
End Function
Step 4: We will now transform this method as a PageMethod and then call this method GetContactName() from client side code; i.e. using JavaScript. To enable the method as a PageMethod, add the attribute [WebMethod] on top of the method:
C#
[System.Web.Services.WebMethod]
public static string GetContactName(string custid)
{
}
VB.NET
_
Public Shared Function GetContactName(ByVal custid As String) As String
End Function
At the sametime, add the attribute EnablePageMethods="true" to the ScriptManager as shown below:
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true"/>
Step 5: Let us now create the JavaScript that will call this server side code. Add a javascript file called script.js to your solution (Right Click Project > Add New Item > Jscript File > Rename file to script.js). Add the following code to the javascript file.
function CallMe(src,dest)
{
var ctrl = document.getElementById(src);
// call server side method
PageMethods.GetContactName(ctrl.value, CallSuccess, CallFailed, dest);
}
// set the destination textbox value with the ContactName
function CallSuccess(res, destCtrl)
{
var dest = document.getElementById(destCtrl);
dest.value = res;
}
// alert message on some failure
function CallFailed(res, destCtrl)
{
alert(res.get_message());
}
Step 6: We now need to reference this JavaScript file from our aspx page and invoke the ‘CallMe()’ method whenever the textbox loses focus. To do so:
Add a reference to the javascript file in the body tag as shown below:
<body>
<script type="text/javascript" language="javascript" src="script.js"> script>
<form id="form1" runat="server">
………
Step 7: To invoke the methods whenever the textbox looses focus, add these lines of code in the Page_Load() event
C#
if (!Page.IsPostBack)
{
txtId1.Attributes.Add("onblur", "javascript:CallMe('" + txtId1.ClientID + "', '" + txtContact1.ClientID + "')");
txtId2.Attributes.Add("onblur", "javascript:CallMe('" + txtId2.ClientID + "', '" + txtContact2.ClientID + "')");
}
VB.NET
If (Not Page.IsPostBack) Then
txtId1.Attributes.Add("onblur", "javascript:CallMe('" & txtId1.ClientID & "', '" & txtContact1.ClientID & "')")
txtId2.Attributes.Add("onblur", "javascript:CallMe('" & txtId2.ClientID & "', '" & txtContact2.ClientID & "')")
End If
As shown above, we are using the Attributes.Add that lets us add an attribute to the server control’s System.Web.UI.AttributeCollection object. The function ‘CallMe’ kept in the ‘script.js’ file will be invoked. We are passing the source and destination textboxes as parameters. The source textbox will contain the CustomerID. The CustomerID will be looked up in the Customers table and the corresponding ‘ContactName’ will be retrieved in the destination textbox.
Well that is all that is needed to invoke server side code from client side. Run the code. Type ‘ALFKI’ in the first textbox and hit the tab key. You will see that the javascript function goes ahead and calls the PageMethod GetContactName() using PageMethods.GetContactName. It passes the value of the source textbox which contains the CustomerID. The ‘ContactName’ returned is displayed in the second textbox below the first one, in our case the value displayed is ‘Maria Anders’.
Troubleshooting: ‘PageMethods Is 'Undefined'’ error
1. Try setting EnablePageMethods="true" in the script manager tag
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true"/>
2. Don't add the javascript references or code in the section. Add it to the tag.
<body>
<script type="text/javascript" language="javascript" src="script.js"> script>
<form id="form1" runat="server">
form>
body>
3. Page methods needs to be static in code behind.
hind.
I hope you have got an idea of how to call server side code using JavaScript. I have used this technique successfully in a few projects and just love and admire PageMethods. I hope you found this article useful and I thank you for viewing it. The source code for this article can be downloaded from here.

Wednesday, May 4, 2011

TRY…CATCH and ERROR Handling-Sql Server 2005

Syntax:
BEGIN TRY
{ sql_statement
|
statement_block }
END TRY
BEGIN CATCH
{ sql_statement
|
statement_block }
END CATCH

The TRY or CATCH block can contain a single T-SQL statement or a series of statements. The CATCH block must follow immediately after the TRY block. The TRY/CATCH block cannot span more than a single batch. In addition, TRY/CATCH block cannot span an IF/ELSE statement.

Example of TRY…CATCH:
BEGIN TRY
DECLARE @X INT
---- Divide by zero to generate Error
SET @X = 1/0
PRINT 'Command after error in TRY block'
END TRY
BEGIN CATCH
PRINT 'Error Detected'
END CATCH
PRINT 'Command after TRY/CATCH blocks'

Above code will return following result:

Error Detected
Command after TRY/CATCH blocks


If all the statements within the TRY block are executed successfully, then processing does not enter the CATCH block, but instead skips over the CATCH block and executes the first statement following the END CATCH statement. Removing SET statement in above code PRINT ‘Error Detected’ statement is not executed, but the PRINT statement within the TRY block is executed, as well as the PRINT statement after the TRY/CATCH block. TRY/CATCH blocks can be nested.

Limitation of TRY…CATCH:

  • Compiled errors are not caught.
  • Deferred name resolution errors created by statement level recompilations. (If process is terminated by Kill commands or broken client connections TRY…CATCH will be not effective)
  • Errors with a severity greater than 10 that do not terminate their database connection are caught in the TRY/CATCH block.

For errors that are not trapped, SQL Server 2005 passes control back to the application immediately, without executing any CATCH block code.


Functions to be used in CATCH block are :

  • ERROR_NUMBER: returns the error number, and is the same value of @@ERROR.
  • ERROR_SEVERITY: returns the severity level of the error that invoked the CATCH block.
  • ERROR_STATE: returns the state number of the error.
  • ERROR_LINE: returns the line number where the error occurred.
  • ERROR_PROCEDURE: returns the name of the stored procedure or trigger for which the error occurred.
  • ERROR_MESSAGE: returns the full message text of the error. The text includes the values supplied for any substitutable parameters, such as lengths, object names, or times.

You can use these functions anywhere inside a CATCH block, and they will return information regarding the error that has occurred. These functions will return the value null outside of the CATCH block.

Similar example of TRY…CATCH which includes all the ERROR functions:
USE AdventureWorks;
GO
BEGIN TRY
-- Generate a divide-by-zero error.
SELECT 1/0;
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber,
ERROR_SEVERITY() AS ErrorSeverity,
ERROR_STATE() AS ErrorState,
ERROR_PROCEDURE() AS ErrorProcedure,
ERROR_LINE() AS ErrorLine,
ERROR_MESSAGE() AS ErrorMessage;
END CATCH;
GO

Tuesday, May 3, 2011

Table Variables

Q1: Why were table variables introduced when temporary tables were already available?

A1: Table variables have the following advantages over temporary tables:
  • As mentioned in the SQL Server Books Online "Tables" article, table variables, such as local variables, have a well defined scope at the end of which they are automatically cleared.
  • Table variables result in fewer recompilations of a stored procedure as compared to temporary tables.
  • Transactions that involve table variables last only for the duration of an update on the table variable. Therefore, table variables require less locking and logging resources. Because table variables have limited scope and are not part of the persistent database, transaction rollbacks do not affect them.
Q2: What does it mean by saying that table variables result in fewer recompilations of a stored procedure than when temporary tables are used?

A2: The following article discusses some reasons when stored procedures are recompiled:

243586 (http://support.microsoft.com/kb/243586/ ) Troubleshooting stored procedure recompilation
The "Recompilations Due to Certain Temporary Table Operations" section also lists some requirements to avoid such as a recompilation because of temporary tables. These restrictions do not apply to table variables.

Table variables are completely isolated to the batch that creates them so no 're-resolution' has to occur when a CREATE or ALTER statement takes place, which may occur with a temporary table. Temporary tables need this 're-resolution' so the table can be referenced from a nested stored procedure. Table variables avoid this completely so stored procedures can use plan that is already compiled, thus saving resources to process the stored procedure.

Q3: What are some of the drawbacks of table variables?

A3: These are some of the drawbacks as compared to temporary tables:
  • Non-clustered indexes cannot be created on table variables, other than the system indexes that are created for a PRIMARY or UNIQUE constraint. That can influence the query performance when compared to a temporary table with non-clustered indexes.
  • Table variables do not maintain statistics like temporary tables can. Statistics cannot be created on table variables through automatic creation or by using the CREATE STATISTICS statement. Therefore, for complex queries on large tables, the lack of statistics may deter the optimizer to determine the best plan for a query, thus affecting the performance of that query.
  • The table definition cannot be changed after the initial DECLARE statement.
  • Tables variables cannot be used in a INSERT EXEC or SELECT INTO statement.
  • CHECK constraints, DEFAULT values, and computed columns in the table type declaration cannot call user-defined functions.
  • You cannot use the EXEC statement or the sp_executesql stored procedure to run a dynamic SQL Server query that refers a table variable, if the table variable was created outside the EXEC statement or the sp_executesql stored procedure. Because table variables can be referenced in their local scope only, an EXEC statement and a sp_executesql stored procedure would be outside the scope of the table variable. However, you can create the table variable and perform all processing inside the EXEC statement or the sp_executesql stored procedure because then the table variables local scope is in the EXEC statement or the sp_executesql stored procedure.
Q4: Are table variables memory-only structures that are assured better performance as compared to temporary or permanent tables, because they are maintained in a database that resides on the physical disk?

A4: A table variable is not a memory-only structure. Because a table variable might hold more data than can fit in memory, it has to have a place on disk to store data. Table variables are created in the tempdb database similar to temporary tables. If memory is available, both table variables and temporary tables are created and processed while in memory (data cache).

Q5: Do I have to use table variables instead of temporary tables?

A5: The answer depends on these three factors:
  • The number of rows that are inserted to the table.
  • The number of recompilations the query is saved from.
  • The type of queries and their dependency on indexes and statistics for performance.
In some situations, breaking a stored procedure with temporary tables into smaller stored procedures so that recompilation takes place on smaller units is helpful.

In general, you use table variables whenever possible except when there is a significant volume of data and there is repeated use of the table. In that case, you can create indexes on the temporary table to increase query performance. However, each scenario may be different. Microsoft recommends that you test if table variables are more helpful than temporary tables for a particular query or stored procedure.

Popular Posts

Recent Posts

Unordered List

Text Widget