Friday, June 25, 2010

Use of SQL Profiler


How To: Use SQL Profiler


Overview

You can use the SQL Profiler tool to debug, troubleshoot, monitor, and measure your application's SQL statements and stored procedures. SQL Profiler captures activity occurring in SQL Server, driven by requests from your client application.

The tool enables you to select precisely which events you want to monitor. For example, you might want to see when stored procedures are called, when they complete, how long they take to execute, how many logical reads occur during execution, and so on. You can also filter the trace, which is particularly useful when your database is under heavy load and a large amount of trace information is generated. SQL Profiler provides a set of templates with predefined event selection criteria. The templates are designed to capture commonly required events. You can modify and extend the templates or create your own. Trace data can be displayed interactively, or it can be captured directly to a trace file or database table.

What You Must Know

When you begin profiling, the following guidelines will help you use the tool most effectively:

  • Filter the captured information. In a high-traffic database, filtering enables you to capture only the required information. Consider using one of the predefined filters to:

· Filter by ApplicationName to trace data specific to one application.

· Filter by DatabaseName specify to your application if the server is hosting several databases.

· Filter by Duration to measure query performance.

· Filter by a specific object in ObjectName, and by a specific user in LoginName.

  • Consider saving trace information to a file. Instead of watching the trace information on-screen, you can capture the results to a file. This technique is useful for offline analysis. You can also use captured trace information as input to the SQL Server Index Tuning Wizard or insert it into a SQL Server table.

Note Sending trace data directly to a SQL Server table can incur performance overhead. It is often better to trace to a file and then import the data to a table later.

To save trace output to a file from the trace output window, click Save As on the File menu, click Trace File, and then specify a file location and a name. Trace files are given the .trc extension.

To capture output directly to a file, specify the file name details on the General tab of the Trace Properties dialog box. You should also set the maximum file size to prevent the file from growing indefinitely. Then when the file reaches the maximum size, a new file will be created.

  • Consider saving data to a file before sending it to a database table. The interception mechanism for capturing information can itself slow the application, depending on the volume of data captured and the number of client requests. Capturing profiler data to a database table is relatively slow compared to saving to a file. If you need to save data to database table, consider saving the data to a file first and then importing it to a database table. Doing so reduces the trace overhead and improves trace performance.

The following statement creates a table named 1108 in the current database and imports the trace information from MyTrace.trc into that table.

Copy Code

SELECT * INTO trace1108 FROM ::fn_trace_gettable('C:\MyTrace.trc', default)

Default Templates

SQL Server provides eight predefined templates to track events for a set of common tasks. These templates are described in Table 1 together with typical usage scenarios.

Table 1: Default Templates

Template name

Description

Usage scenario

SQLProfilerSP_Counts

Contains events to track how often stored procedures are executed.

Use to identify the most commonly used stored procedure, so that you can fine-tune it.

SQLProfilerStandard

Captures an extensive range of events and data.

Use as a start point or for general monitoring purposes.

SQLProfilerTSQL

Captures events that relate to Transact SQL (T-SQL).

Use to intercept and verify SQL statements for debugging purposes.

SQLProfilerTSQL_Duration

Events for measuring the execution cost (duration in milliseconds) of T-SQL queries and stored procedures.

Use to track down long - running queries.

SQLProfilerTSQL_Grouped

Similar to SQLProfilerStandard, but with information grouped and organized. Use as a start point for general monitoring and troubleshooting.

Because this template groups information by user, it can be used to track requests specific to a problematic user. An example is an application that uses Windows® authentication to connect to SQL Server, where problems are occurring that relate to a specific user.

SQLProfilerTSQL_Replay

Captures events that can be used to replay the exact steps at a later stage or on another server.

Use to troubleshoot and reproduce problems.

SQLProfilerTSQL_SPs

Provides extensive logging for stored procedures, including queries executed within stored procedures.

Use to troubleshoot stored procedures.

SQLProfilerTuning

Contains events needed to capture the execution cost and related data.

Use to track query costs.

The remainder of this How To shows you how to profile two common performance-related scenarios using SQL Profiler.

Isolating a Long-Running Query with SQL Profiler

If your application has a performance problem that you think might be caused by a particularly long-running query, you can use the SQLProfilerTSQL_Duration template to analyze query durations. You can either analyze the queries interactively, or you can save information to an output file and analyze the data offline.

Identifying a Long-Running Query Interactively

The most immediate way of analyzing query performance is to use SQL Profiler to show trace information interactively.

To identify a long-running query interactively

  1. Start SQL Profiler.
  2. On the File menu, click New, and then click Trace.
  3. Specify the relevant connection details to connect to the computer running SQL Server.

The Trace Properties dialog box appears.

  1. In the Template name list, click SQLProfilerTSQL_Duration.
  2. Click the Events tab.

Notice that two key events are selected:

    • RPC:Completed from the Stored Procedures event class
    • SQL:BatchCompleted from the T-SQL event class
  1. Click Run to run the trace.
  2. Start SQL Query Analyzer.
  3. Run the queries you want to analyze. For example, using the Pubs database, you might run the following query.

Copy Code

select au_id, au_lname + ' ' + au_fname, phone from authors where au_lname like 'G%' order by au_lname
select * from authors
Select au_id from authors
  1. View the trace output in SQL Profiler. Note that durations are given in milliseconds.

Figure 1 shows sample output.


Figure 1: Sample SQL Profiler output using the SQLProfilerTSQL_Duration template

  1. Stop the trace.

Note Your duration times may vary from those shown, and may even appear as zero if the database server has a small load.

Identifying a Long-Running Query from Trace Output

As an alternative to the interactive approach, you can save trace information to an output file and analyze the data offline. The trace information can then be imported into a database table for further analysis. This approach is useful where large sets of trace data need to be analyzed.

The following steps show you how to save trace data to a trace file and then import it into a trace table for analysis. A stored procedure named AnlzTrcExec is provided to aid in data analysis.

Note When trace data is saved to a file, the values in the EventClass column are converted into integer values. To increase readability, the AnlzTrcExec procedure uses a lookup table named trace_events so that the event class can be displayed as text.

To identify a long-running query from trace output

  1. In SQL Profiler, on the File menu, click New, and then click Trace.
  2. Specify the relevant connection details to connect to the computer running SQL Server.

The Trace Properties dialog box appears.

  1. In the Template name list, select SQLProfilerTSQL_Duration.
  2. Select the Save to file check box, specify the trace file name as c:\MyTrace.trc, and then click Save.
  3. On the Data Columns tab, select the following data columns, clicking Add after each selection:
    • CPU
    • IntegerData
    • Reads
    • StartTime
    • Writes
  4. Click Run.
  5. In SQL Query Analyzer, run the queries you want to analyze. For example, using the Pubs database, you might run the following query.

Copy Code

select au_id, au_lname + ' ' + au_fname, phone from authors where au_lname like 'G%' order by au_lname
select * from authors
Select au_id from authors
  1. Stop the trace.
  2. In SQL Query Analyzer, import the trace file into the database of your choice by using the following query:

Copy Code

SELECT * INTO MyTraceTable FROM ::fn_trace_gettable('C:\MyTrace.trc', default)
  1. Run the following query to create a trace events lookup table.

Copy Code

if exists (select * from dbo.sysobjects
    where id = object_id(N'[trace_events]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
    drop table [trace_events]
 create table trace_events ([EventClass] int, [EventName] varchar(31))
 Insert trace_events values (10,'RPC:Completed')
 Insert trace_events values (11,'RPC:Starting')
 Insert trace_events values (12,'SQL:BatchCompleted')
 Insert trace_events values (13,'SQL:BatchStarting')
 Insert trace_events values (14,'Login')
 Insert trace_events values (15,'Logout')
 Insert trace_events values (16,'Attention')
 Insert trace_events values (17,'ExistingConnection')
 Insert trace_events values (18,'ServiceControl')
 Insert trace_events values (19,'DTCTransaction')
 Insert trace_events values (20,'Login Failed')
 Insert trace_events values (21,'EventLog')
 Insert trace_events values (22,'ErrorLog')
 Insert trace_events values (23,'Lock:Released')
 Insert trace_events values (24,'Lock:Acquired')
 Insert trace_events values (25,'Lock:Deadlock')
 Insert trace_events values (26,'Lock:Cancel')
 Insert trace_events values (27,'Lock:Timeout')
 Insert trace_events values (28,'DOP Event')
 Insert trace_events values (33,'Exception')
 Insert trace_events values (34,'SP:CacheMiss')
 Insert trace_events values (35,'SP:CacheInsert')
 Insert trace_events values (36,'SP:CacheRemove')
 Insert trace_events values (37,'SP:Recompile')
 Insert trace_events values (38,'SP:CacheHit')
 Insert trace_events values (39,'SP:ExecContextHit')
 Insert trace_events values (40,'SQL:StmtStarting')
 Insert trace_events values (41,'SQL:StmtCompleted')
 Insert trace_events values (42,'SP:Starting')
 Insert trace_events values (43,'SP:Completed')
 Insert trace_events values (44,'Reserved ')
 Insert trace_events values (45,'Reserved ')
 Insert trace_events values (46,'Object:Created')
 Insert trace_events values (47,'Object:Deleted')
 Insert trace_events values (48,'Reserved')
 Insert trace_events values (49,'Reserved')
 Insert trace_events values (50,'SQL Transaction')
 Insert trace_events values (51,'Scan:Started')
 Insert trace_events values (52,'Scan:Stopped')
 Insert trace_events values (53,'CursorOpen')
 Insert trace_events values (54,'Transaction Log')
 Insert trace_events values (55,'Hash Warning')
 Insert trace_events values (58,'Auto Update Stats')
 Insert trace_events values (59,'Lock:Deadlock Chain')
 Insert trace_events values (60,'Lock:Escalation')
 Insert trace_events values (61,'OLE DB Errors')
 Insert trace_events values (67,'Execution Warnings')
 Insert trace_events values (68,'Execution Plan')
 Insert trace_events values (69,'Sort Warnings')
 Insert trace_events values (70,'CursorPrepare')
 Insert trace_events values (71,'Prepare SQL')
 Insert trace_events values (72,'Exec Prepared SQL')
 Insert trace_events values (73,'Unprepare SQL')
 Insert trace_events values (74,'CursorExecute')
 Insert trace_events values (75,'CursorRecompile')
 Insert trace_events values (76,'CursorImplicitConversion')
 Insert trace_events values (77,'CursorUnprepare')
 Insert trace_events values (78,'CursorClose')
 Insert trace_events values (79,'Missing Column Statistics')
 Insert trace_events values (80,'Missing Join Predicate')
 Insert trace_events values (81,'Server Memory Change')
 Insert trace_events values (82,'User Configurable')
 Insert trace_events values (83,'User Configurable')
 Insert trace_events values (84,'User Configurable')
 Insert trace_events values (85,'User Configurable')
 Insert trace_events values (86,'User Configurable')
 Insert trace_events values (87,'User Configurable')
 Insert trace_events values (88,'User Configurable')
 Insert trace_events values (89,'User Configurable')
 Insert trace_events values (90,'User Configurable')
 Insert trace_events values (91,'User Configurable')
 Insert trace_events values (92,'Data File Auto Grow')
 Insert trace_events values (93,'Log File Auto Grow')
 Insert trace_events values (94,'Data File Auto Shrink')
 Insert trace_events values (95,'Log File Auto Shrink')
 Insert trace_events values (96,'Show Plan Text')
 Insert trace_events values (97,'Show Plan ALL')
 Insert trace_events values (98,'Show Plan Statistics')
 Insert trace_events values (99,'Reserved')
 Insert trace_events values (100,'RPC Output Parameter')
 Insert trace_events values (101,'Reserved')
 Insert trace_events values (102,'Audit Statement GDR')
 Insert trace_events values (103,'Audit Object GDR')
 Insert trace_events values (104,'Audit Add/Drop Login')
 Insert trace_events values (105,'Audit Login GDR')
 Insert trace_events values (106,'Audit Login Change Property')
 Insert trace_events values (107,'Audit Login Change Password')
 Insert trace_events values (108,'Audit Add Login to Server Role')
 Insert trace_events values (109,'Audit Add DB User')
 Insert trace_events values (110,'Audit Add Member to DB')
 Insert trace_events values (111,'Audit Add/Drop Role')
 Insert trace_events values (112,'App Role Pass Change')
 Insert trace_events values (113,'Audit Statement Permission')
 Insert trace_events values (114,'Audit Object Permission')
 Insert trace_events values (115,'Audit Backup/Restore')
 Insert trace_events values (116,'Audit DBCC')
 Insert trace_events values (117,'Audit Change Audit')
 Insert trace_events values (118,'Audit Object Derived Permission')
 Go
  1. Create a stored procedure named AnlzTrcExec by running the following code:

Copy Code

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[AnlzTrcExec]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
 drop procedure [dbo].[AnlzTrcExec]
 GO
 
 Create  Proc AnlzTrcExec @trc nvarchar(255), @len int = 60, @Top int = 100, @EventClass nvarchar(20) = 'all', @TextData nvarchar(255) = 'none' as
 declare @cmd nvarchar(2048)
 declare @TopV as nvarchar(20)
 SET @TopV = ' 100 PERCENT '
 if @Top != 100
 BEGIN
   SET @TopV = ' ' + cast(@Top as nvarchar(4)) + ' '
 END
 set @cmd = ' SELECT TOP' + @TopV + ' e.EventName,
 Count(*) as CountOfEvents,AVG(Duration) AS AvgDuration,MIN(Duration) AS MinDuration,MAX(Duration) AS MaxDuration,
 SUM(a.Duration) AS [SumDuration],SUBSTRING(a.TextData, 1, '+ cast(@Len as nvarchar(4)) + ') AS [Substring from Text Data],
 MIN(starttime) as MinStartTime,MAX(starttime) as MaxStartTime,AVG(CPU) AS AvgCPU,MIN(CPU) AS MinCPU,MAX(CPU) AS MaxCPU,
 AVG(Reads)AS AvgReads,MIN(Reads) AS MinReads,MAX(Reads) AS MaxReads,AVG(Writes) AS AvgWrites,MIN(Writes) AS MinWrites,
 MAX(Writes) AS MaxWrite,AVG(IntegerData) AS AvgIntegerData,MIN(IntegerData) AS MinIntegerData,MAX(IntegerData) AS MaxIntegerData
   FROM dbo.' + @Trc +' a LEFT OUTER JOIN
        dbo.trace_events e
     ON a.EventClass = e.EventClass
   WHERE 1=1'
 if @textdata != 'none'
 begin
   set @cmd = @cmd + ' AND a.TextData like ''%' + @TextData + '%'
 end
 if @eventclass != 'all'
 begin
  set @cmd = @cmd + ' AND a.EventClass IN (' + @EventClass + ')'
 end
   set @cmd = @cmd + 
 ' GROUP BY SUBSTRING(a.TextData, 1, '+ cast(@Len as nvarchar(4)) + '), e.EventName
   HAVING (SUM(a.Duration) > 0)
   ORDER BY SUM(a.Duration) DESC'
   exec(@cmd)
GO

Note The AnlzTrcExec procedure is used to analyze the trace events used within this How To. It uses the trace_events table to provide English output names for the EventClass column and also provides several summary options. The stored procedure takes up to four parameters: trace table name, number of characters to group on from the query text, number of queries to return information for, and event class name. Only the trace table name is required.

  1. Run the stored procedure using the following statement.

Copy Code

AnlzTrcExec 'MyTraceTable'

Trace data is displayed using default options.

Note Only queries with a nonzero duration are shown in the summary information.

  1. Run the following query.

Copy Code

AnlzTrcExec 'MyTraceTable', 20, 10, 41

The top 10 'SQL:StmtCompleted' events are returned (ordered by the sum of duration) grouped on the first 20 characters of each query text.

Filtering Events

You can use a filter to view only those queries that take longer than a specified duration.

To filter based on duration

  1. Stop the trace if it is currently running, either by clicking the Stop selected trace icon on the toolbar or by clicking Stop Trace on the File menu.
  2. On the File menu, click Properties.

The Trace Properties dialog box appears.

  1. On the Filters tab, expand Duration from Trace event criteria, and then expand Greater than or equal to and enter a value.. A value of 1000 milliseconds, for example, would cause the filter to show only those queries that take longer than one second to run.
  2. Click Run.
  3. Run the queries you want to analyze. For example, using the Pubs database:

Copy Code

select au_id, au_lname + ' ' + au_fname, phone from authors where au_lname like 'G%' order by au_lname
select * from authors
Select au_id from authors
  1. Using SQL Profiler, view the trace data. Only information satisfying the filter is captured.

After capturing trace information, you can click the Duration column in the output window to sort in order of duration. You can view the slowest-running queries in the TextData column.

Note If no queries match the filter, you may need to lower the value for the Greater than or equal to value.

Tracking Heavily Used Stored Procedures

If your application uses numerous stored procedures, you may want to target your fine-tuning to those stored procedures that are used most heavily. The SQLProfilerSP_Counts template aids in this process, as described in the steps that follow.

To track heavily used stored procedures

  1. Start SQL Profiler.
  2. On the File menu, click New, and then click Trace.
  3. Specify the relevant connection details to connect to the computer running SQL Server.

The Trace Properties dialog box appears.

  1. In the Template name list, select SQLProfilerSP_Counts.
  2. Click Run to run the trace.

Running the trace displays the following events: EventClass, ServerName, DatabaseID, ObjectID and SPID.

The most frequently referenced ObjectIDs are listed first.

  1. You can now run your client application and begin database profiling. Figure 2 shows sample output.


Figure 2: Sample SQL Profiler output using the SQLProfilerSP_Counts template

Identifying Stored Procedures

To find the name of the stored procedure given a specific ObjectID, you can use the following query. Replace <ObjectID> with the value you see in the SQL Profiler output window.

Copy Code

Select name from sysobjects where id = 

Identifying Execution Duration

If you want to find out how long a stored procedure took to run, you need to capture the SP:Completed event. To identify the execution duration of individual statements within a stored procedure, use SP:StmtCompleted.

To identify stored procedure execution duration

  1. Stop the trace if it is already running.
  2. On the File menu, click Properties.
  3. On the Events tab, expand the Stored procedures event class present in the Available Event Class list box and select SP:Completed.
  4. Click Add, and then click Run.
  5. Run the stored procedures you want to analyze. For example, using SQL Query Analyzer and the Pubs database:

Copy Code

sp_help authors

SQL Query Analyzer displays a list of stored procedure executions.

To identify statement execution duration within a stored procedure

  1. Stop the trace if it is already running.
  2. On the File menu, click Properties.
  3. On the Events tab, expand the Stored Procedures event class and select SP:StmtCompleted.
  4. Click Add, and then click Run.

SQL Profiler shows statement and stored procedure execution.

  1. Run the stored procedures you want to analyze. For example, using SQL Query Analyzer and the Pubs database:

Copy Code

sp_help authors

SQL Query Analyzer displays a list of statement executions.

Tuesday, June 15, 2010

Interview Panel : Asp.Net Questions


View state size Limit :

Maximum view state size limit (128K) exceeded. Actual viewstate size for this page was 174.281K.

Size of Cookies : 4096 Bytes

Dataset Size Limit: 2^32

The default cache size is 128 MB. This is primarily used for hash file data cache in the server. This setting is only can be done in Administrator not in job level. Job level tuning is available only for Buffer Size.

Use of new operator in C#

The new operator is used to create new instances of types. There are three forms of new expressions:

  • Object creation expressions are used to create new instances of class types and value types.
  • Array creation expressions are used to create new instances of array types.
  • Delegate creation expressions are used to create new instances of delegate types.

The new operator implies creation of an instance of a type, but does not necessarily imply dynamic allocation of memory. In particular, instances of value types require no additional memory beyond the variables in which they reside, and no dynamic allocations occur when new is used to create instances of value types.

Main Difference between for and foreach loop :

The for loop executes a statement or a block of statements repeatedly until a specified expression evaluates to false. there is need to specify the loop bounds( minimum or maximum).

int j = 0;

for (int i = 1; i <= 5; i++)
{
j = j + i ;
}


The foreach statement repeats a group of embedded statements for each element in an array or an object collection.you do not need to specify the loop bounds minimum or maximum.

int j = 0;

int[] tempArr = new int[] { 0, 1, 2, 3, 5, 8, 13 };
foreach (int i in tempArr )
{
j = j + i ;
}

Cascade Delete in Sql 2005:

CREATE TABLE test_child

(SUB1 INT,
[NO] int,
FOREIGN KEY ([NO]) REFERENCES Test_parent ON DELETE CASCADE)

Use of ViewStates in ASP.NET


Understanding ViewState in ASP.NET


All server controls have a property called ViewState. If this is enabled, the ViewState for .NET controls is also enabled.

What is ViewState and what it is not?


There are some common misconceptions about ViewState. Let me discuss these points here for the benefit of the readers. ViewState does not hold the controls, rather it holds the values of the form controls and their corresponding ID's that would otherwise be lost due to a post back because they do not post with the form. ViewState is not used to hold session data or to transmit data between pages. ViewState does not recreate the dynamically created controls of a page. It does not restore the values to the controls after a post back operation. Taken aback? Yes, it is true. Even when the ViewState for a control is disabled, still the value would be retained after a post back of the page occurs, for input controls like TextBox or DropDownList. So then, what is ViewState? ViewState represents the state of a page when it was last processed on the web server. It holds the values of a control that has been dynamically changed.


How does ViewState work?


All server controls have a property called ViewState. If this is enabled, the ViewState for the control is also enabled. Where and how is ViewState stored? When the page is first created all controls are serialized to the ViewState, which is rendered as a hidden form field named __ViewState. This hidden field corresponds to the server side object known as the ViewState. ViewState for a page is stored as key-value pairs using the System.Web.UI.StateBag object. When a post back occurs, the page de-serializes the ViewState and recreates all controls. The ViewState for the controls in a page is stored as base 64 encoded strings in name - value pairs. When a page is reloaded two methods pertaining to ViewState are called, namely the LoadViewState method and SaveViewState method. The following is the content of the __ViewState hidden field as generated for a page in my system.

Listing 1

<input type="hidden" name="__VIEWSTATE"
  value="dNrATo45Tm5QzQ7Oz8AblWpxPjE9MMl0Aq765QnCmP2TQ==" />

Enabling and Disabling ViewState

By default, ViewState is enabled for all server controls. ViewState can be enabled and disabled in any of the following ways.

· Page Level

· Control Level

· Application Level

· Machine Level

To enable or disable ViewState in the Page Level, use the following in the Page directive of the ASP.NET page.

Listing 2

<"%@ Page EnableViewState ="False" %"> 
 or 
 <"%@ Page EnableViewState ="True" %">

To enable or disable ViewState at the Control Level, use the following:

Listing 3

<asp:TextBox id="txtCode" runat="server" EnableViewState="false" />
 or
 <asp:TextBox id="txtCode" runat="server" EnableViewState="true" />

To enable or disable ViewState in the Application Level, use the following:

Listing 4

<pages enableViewState="false" />
 or
 <pages enableViewState="true" />

To enable ViewState in the Machine Level, use the following:

Listing 5

<pages enableViewState="true" enableViewStateMac="true" ... />
 or
 <pages enableViewState="false" ... />

Saving and Restoring Values to and from the ViewState


ViewState works with the following types.

· Primitive types

· Arrays of primitive types

· ArrayList and Hashtable

· Any other serializable object

To add an ArrayList object to the ViewState use the following statements.

Listing 6

ArrayList obj = new ArrayList();
 //Some code
 ViewState["ViewStateObject"] = obj;

To retrieve the object later use:


Listing 7

obj = ViewState["ViewStateObject"];

Performance Issues

The size of the ViewState for a page should be minimal for a better performance in page rendering. Remember that the data in the ViewState makes a round trip and incurs more network bandwidth usage. Therefore, ViewState should always be used judiciously. For pages and controls that do not require a post back at all, set the EnableViewState property of the page or the control of the page to false. It is always preferable to keep the ViewState out of the aspx page for performance improvements of the web application. To accomplish this, the methods SavePageStateToPersistenceMedium and LoadPageStateFromPersistenceMedium can be used. Use the following in the web.config or the machine.config file to disable ViewState for all the pages in a particular application or for all applications.

Listing 8

<Pages enableViewState="false"/>

Note that only controls contained within a

tag in the .aspx page can store ViewState. Further, even if ViewState for a page is disabled, still the page itself saves about 20 bytes of information into ViewState to distribute post back data and ViewState values to the correct controls on post back. So, for pages that do not post back at all, remove the runat="server" tag completely for a reduction of the page size by an amount of 20 bytes. This reduction can be substantial for a number of such pages of the application running over the network. ViewState should only be enabled for pages and controls that use it. Avoid using ViewState for controls like the DataGrid and the DataRepeater as the ViewState size for these controls is quite huge. Setting the EnableViewState properties or these controls to false would result in a huge reduction of the size of the rendered html and hence the bandwidth.

During the testing phases of an application, the ViewState size should be tested. I am giving a code below that can detect the size of the ViewState of a page with ease. I have created a MasterPageBase class that all the other pages in the application need to inherit. The code for the class is as shown below.

Listing 9

public class MasterPageBase: System.Web.UI.Page
 {
   protected override void OnPreRender(EventArgs e)
   {
     object viewStateObject = HttpContext.Current.Request["__VIEWSTATE"];
     if (viewStateObject == null)
       HttpContext.Current.Trace.Warn("The ViewState Size is:", "0");
     else
       HttpContext.Current.Trace.Warn("The ViewState Size is:",
         HttpContext.Current.Request["__VIEWSTATE"].Length.ToString());
     base.OnPreRender(e);
   }
 }

Security Issues

For security measures (to ensure that the ViewState is not tampered) one of the following two measures can be adopted.

· Use the EnableViewStateMac property

· Use Encryption of ViewState content

The EnableViewStateMac property ensures a Machine Authentication Check (MAC). This should be set at the page level or in the application’s web.config file. When set, this property appends a hash code to the ViewState before rendering. Whenever a post back occurs, this hash code is recalculated and checked with the one that is stored in the __ViewState hidden field of the form. It they do not match, the page is rejected, thus ensuring that the ViewState is not tampered.

To encrypt the contents of the ViewState, use the following in the machine.config file.

Listing 10

<machineKey validation="3Des" /> or <machineKey validation="SHA1"/>


ViewState Errors


There is a common ViewState error that is often encountered when transferring the control from one aspx page to another. Let there be two aspx pages, first.aspx and second.aspx. Let there be a text box and a submit button in the first.aspx page. If we now use the Server.Transfer in the handler for the submit button click event in the first.aspx page to transfer the control from the page first.aspx to the page second.aspx, a ViewState error would occur. This is because the EnableViewStateMac property of the second.aspx page is set to true by default, just as it is in all other aspx pages. This problem can be overcome by setting the property to false in the second.aspx page.

Conclusion


ASP.NET ViewState is a great feature for web developers. It maintains a state of a page as it moves back and forth. This article has provided an in depth coverage of this State Management Technique of ASP.NET. However, when using ViewState one should be well aware of the performance considerations of its usage. It is preferable to enable tracing for a page to know the size of the ViewState for a page in the development cycle of a project. The ViewState size should be optimized well before the application goes to deployment to avoid lengthy operations in the page load cycles of the pages of your application

Wednesday, June 9, 2010

OOPS Concepts in C#


What is an Abstract class?


An abstract class only allows other classes to inherit from it and cannot be instantiated. When we create an abstract class, it should have one or more completed methods but at least one or more uncompleted methods and these must be preceded by the key word abstract. If all the methods of an abstract class are uncompleted then it is the same as an interface, but there is a restriction that it cannot make a class inherit from it, which means it can not work as a base class.

What is an Interface?


An interface is defined by the key word interface. An interface has no implementation; it only has the definition of the methods without the body. When we create an interface, we are basically creating a set of methods without any implementation. A class implementing an interface must provide the implementation of the interface members. All the methods and properties defined in an interface are by default public and abstract.


Define an Abstract Class


In the following code listing an abstract class named Product has been defined.


Listing 1

public abstract class Product
{
  //fields
  protected string id;
  protected double price;
  //properties
  public abstract string ID
  {
    get;
    set;
  }
 
  public abstract double Price
  {
    get;
    set;
 
  }
  public abstract double CalculatePrice();
}

Define an Interface

In the following code listing an interface named Iproduct has been defined.


Listing 2

public interface Iproduct
{
  string ID
  {
    get;
    set;
 
  }
 
  double Price
  {
    get;
    set;
 
  }
  double CalculatePrice();
}

Implementation

In the following code listing the Iproduct interface has been implemented by the class implementInterface.


Listing 3


public class implementInterface: Iproduct
{
  protected string id;
  protected double price;
  public string ID
  {
    get
    {
      return id;
    }
    set
    {
      id = value;
    }
  }
  public double price
  {
    get
    {
      return price;
    }
    set
    {
      price = value;
    }
 
  }
  public double CalculatePrice()
  {
    return Price * 1.25;
  }

In the following code listing the abstract Class named Product has been implemented by the class implementAbstract.


Listing 4


public class implementAbstract: Product
{
  public override string ID
  {
    get
    {
      return id;
    }
    set
    {
      id = value;
    }
 
  }
  public override double Price
  {
    get
    {
      return price;
    }
    set
    {
      price = value;
    }
 
  }
  public override double CalculatePrice
  {
    return Price * 1.25;
  }
 
}

How to Test

In the following code listing abstract class implementation is being tested.


Listing 5


ImplementAbstract testAbstract=new implementAbstract();
testAbstract.ID=”A1”;
testAbstract.Price=1000.00;
double amt=testAbstract.CalculatePrice();
Response.Write(“Total Net Price of Product : “ +” “+testAbstract.ID +” “+ “is”+” “+amt);
Response.Write(“
”);

In the following code listing the implementation of our interface is being tested.


Listing 6


ImplementInterface testInterface=new implementInterface();
testInterface.ID=”B1”;
testInterface.Price=900.00;
double Iamt= testInterface.CalculatePrice();
Response.Write(“Total Net Price of Product : “ +” “+testInterface.ID +” “+ “is”+” “+Iamt);
Response.Write(“
”);

It should be noted that static members are not inherited under any circumstances. Hence we can not declare a static method in an interface because interfaces have no implementation. We can, however, declare a method as static in an abstract class, because abstract classes can have implementations of static methods. This has been described in the following code listing:


Listing 7


In an abstract class:

public static void test()
{
}

But we can not write the following in an interface.

Listing 8

static void test();

Abstract Class vs. Interface


An abstract class may contain complete or incomplete methods. Interfaces can contain only the signature of a method but no body. Thus an abstract class can implement methods but an interface can not implement methods.

An abstract class can contain fields, constructors, or destructors and implement properties. An interface can not contain fields, constructors, or destructors and it has only the property's signature but no implementation.

An abstract class cannot support multiple inheritance, but an interface can support multiple inheritance. Thus a class may inherit several interfaces but only one abstract class.

A class implementing an interface has to implement all the methods of the interface, but the same is not required in the case of an abstract Class.

Various access modifiers such as abstract, protected, internal, public, virtual, etc. are useful in abstract Classes but not in interfaces.

Abstract classes are faster than interfaces.


Sealed Class


Classes can be declared as sealed. This is accomplished by putting the sealed keyword before the keyword class in the class definition. For example:

Listing 9

public sealed class classSealed
{
  // Class members here.
  public string ID;
  public double Price;
}
 

In the following code listing the implementation of a sealed class has been tested.


Listing 10

classSealed sc=new classSealed();
sc.ID=”C1”;
sc.Price=500.00;
double Samt=sc. CalculatePrice();
Response.Write(“Total Net Price of Product : “ +” “+sc.ID +” “+ “is”+” “+Samt);
Response.Write(“
”);
 

A sealed class cannot be used as a base class. For this reason, it cannot also be an abstract class. Sealed classes are primarily used to prevent derivation. Because they can never be used as a base class, some run-time optimizations can make calling sealed class members slightly faster. Sealing a class means one can not derive from it. Sealing a method means one can not override it. In C# structs are implicitly sealed; therefore, they cannot be inherited. If we try to inherit from a sealed class in another class we will get compile time error about Inconsistent accessibility (code is shown in following code listing).


Listing 11

public class TestClass : classSealed
{
}
 

In C# a method can not be declared as sealed. However when we override a method in a derived class, we can declare the overridden method as sealed as shown below. By declaring it as sealed, we can avoid further overriding of this method.

Listing 12

public class testClass
{
  public int x;
  public int y;
  public virtual void testMethod(){
 
  }
 
}
 
public class TestClass: testClass
{
  public override sealed void testMethod(){
 
  }
}