ThreadAbortException

April 2005 Entries

Loading pages in IFRAME dynamically from codebehind - ASP.NET

 

Most of us who develop Web Applications would have used an IFRAME during some stage of our lives. IFRAME's are an easy way by which you can embed another page within your original page such that you can show some important information like Stock position/Weather from another site without worrying about the changes happening to that site and updating the same. The Frame can also be used to show another page from your own application.

ASP.NET also provides the option to have an IFRAME in our ASPX Pages. It can be with/without the "runat=server" attribute and does serve the purpose of embedding the page. The source for the frame can be set as follows:-

 

<IFRAME id="frame1" src="SourcePage.extension / URL of the external Site" scrolling="auto">
</IFRAME>


However, in practical scenarios, we may want to load the page dynamically. In other words, we may want to specify the "src" attribute (the page which we want to show), dynamically. There is no straight forward way to do that and even if you add a "runat=server" attribute to it (though required in the work around provided below), you cannot access the "src" property directly.

The workaround to do that is as follows:-

1. Specify the "runat=server" attribute as follows in the ASPX Page:-

<IFRAME id="frame1" scrolling="auto" runat="server">
</IFRAME>

2. In the codebehind, you may need to declare a HtmlGenericControl in the control declarations section as follows:-

C#
protected System.Web.UI.HtmlControls.HtmlGenericControl frame1; (not required if working with ASP.NET  2.0, 3.5 i.e. Visual Studio 2005, 2008)
 
VB.NET
Protected WithEvents frame1 As System.Web.UI.HtmlControls.HtmlGenericControl (not required if working with ASP.NET  2.0, 3.5 i.e. Visual Studio 2005, 2008)
 
3. Then, you need to do a findcontrol to identify the control on the page and typecast it as follows:-
C#
HtmlControl frame1 = (HtmlControl)this.FindControl("frame1"); (not required if working with ASP.NET  2.0, 3.5 i.e. Visual Studio 2005, 2008)
 
VB.NET
Dim frame1 As HtmlControl = CType(Me.FindControl("frame1"), HtmlControl) (not required if working with ASP.NET  2.0, 3.5 i.e. Visual Studio 2005, 2008)

Note: You can have different name for the Generic Control you define in the code behind, but for ease I keep both the same. The "frame1" referred in Find Control is the ID as declared in the ASPX Page.

4. Thereafter, you will be able to access the src property as follows:-

 
C#
frame1.Attributes["src"] = "http://www.live.com" ;

 
VB.NET
frame1.Attributes("src") = "http://www.live.com" ;

  
NOTE: Thanks PhOeNiX for providing the VB.NET equivalent.  I have added the same now.
As you can see though I have hard-coded the URL you can assign it dynamically based on a condition or any other business logic.

This serves the purpose of dynamically loading the page in the IFRAME.
A related article on Triggering an event in the Parent Page from within Page inside IFRAME

Cheers !!!

ASP.NET 2.0 : Accessing controls in Previous Page

Hi,

In my earlier
article, I explained how the PostBackUrl property has made the job of posting the page to a different page easy in Whidbey.

There is a more effective way of accessing the Controls in the previous page. Its using the PreviousPage property of the Page.

Say we have a page Default.aspx with a Textbox "Text1" and a Button "Button1".

There are two ways on how we can access the controls in Default.aspx from another page.

1. Setting the PostBackUrl property of the Button to the New Page, as follows:-

<asp:Button ID="button1" Runat=server Text="submit" PostBackUrl="~/NewPage.aspx" />

Then, in the NewPage.aspx, you can access the TextBox control on Default.aspx as follows:-


public void page_load()
{

TextBox tb = (TextBox)PreviousPage.FindControl("text1");
Response.Write(tb.Text);
}


Note that a new TextBox tb is declared and typecasted using the PreviousPage and FindControl of the ID of the Control in the Previous Page.

2. The other way is the old way of transferring the page to new page using Server.Transfer on the Click Event of the Button in the first page.

But in this case, the PostBackUrl property should not be specified for the Button control.

In the Button declaration in Default.aspx, the code should be

<asp:Button ID="button1" Runat=server Text="submit" OnClick="button1_Click" />

Then, in the codebehind,

void button1_Click(object sender, EventArgs e)
{
Server.Transfer("NewPage.aspx");
}

Still the PreviousPage.FindControl method would work.

This is a wonderful way of accessing the Controls in the Previous Page and I reckon it would be very useful for Developers.

Thanks.

ASP.NET 2.0: The New Compilation Model

One of the excellent features that .NET introduced was the separation of design and code in separate sections by virtue of the code-behind functionality.

A little briefing about the above model for the benefit of those who are new to .NET. In traditional ASP, one has to embed his code as well as HTML design within a single ASP Page. That means, the page would look like a chunk of codes and very difficult in debugging and even while developing, for that matter.

In .NET, the concept of Codebehind files, a way by which you can have all your application logic separately written in a file and have just design and declaration of controls in a page and relate these pages by the attribute Codebehind in the Page directive. Having said this, .NET also provided the flexibility for having the logic within the ASPX Page itself within the script tags. This was referred to as Code inline.

However, there were some hiccups in this mode.

1. The Intellisense (Autocompletion, suggestion etc.,) features were not available in the Code Inline Model.

2. The Code behind file requires compilation (rebuilding) for any changes made.

This was a little tricky because the whole application's logic lies within the DLL file (which is available in the BIN Folder of the application root) and even a small change requires rebuilding the whole application.

However, the Development Team from Microsoft has heard to the queries and have responded in a new robust compilation model.

The following are the new features available in Whidbey (Kindly note that it is still a Beta version which I am exploring and the actual functionalities may change with the release of the Original version. However, we can rest assure they would only get better with the Original version since the Developers are constantly hearing from the Evangelists and Partners and implementing their feedbacks).

1. Dynamic Compilation extended to Code-behind files.
The code-behind files don't need to be compiled for each and every change. Which means just as ASPX pages are dynamically compiled, the codebehind files are also compiled dynamically. I am sure this should be a great boon for the developers (like me) who have been complaining about rebuilding the application for small changes.

2. Intellisense and Auto-completion extended to Inline Code.
Now, whether you type your code in the codebehind file or put it in as inline code in the ASPX page, you will get the cool intellisense which can help you many times in finishing (and finding :) ) the methods. Now its up to the developer to decide which method (inline or codebehind) to follow.

3. No more control declarations in the Codebehind file.
If you examine the Codebehind files in .NET 1.x versions you will find that all the controls in the ASPX page declared are also declared in the codebehind file with the "protected" access specifier ("protected withevents" in vb.net). This may introduce problems when some of these declarations are removed or don't match with that of the ASPX Pages.

Now, in Whidbey there is no more declaration of such kind in the codebehind file. That means, you declare it in one place and thats it. There will be no more declaration in the codebehind files.

There are many other features such as Precompilation Support, Intellisense and Drag n Drop in HTML View etc., which I would dicuss in future articles.

Cheers and Happy Progamming !!!

ASP.NET 2.0 : Passing data between Pages

Hi,

One of the hinderances we had in earlier verions of ASP.NET (1.1 & 1.0 versions) were that, to pass data between pages, we need to use QueryString, Server.Transfer, Sessions etc.,. This was a little surprising for people who come from ASP background who are used to <form method="post" action="newpage.asp">

They can easily get values using Request.Form and posting to new page was as simple as specifying in the action tag the page where they want to post.

However, in ASP.NET, by default all the pages post to themselves. That means, you cannot set the action page and if you want to do so, you need to remove the "runat=server" attribute which will disable the other extraordinary features provided in .NET. So naturally passing values between pages was a little tricky.

In Whidbey, the developers have listened to the queries and come up with a wonderful solution, i.e. the PostBackUrl property.

The PostBackUrl specifies which page to be posted to, upon submitting the page. The syntax is as follows:-

<asp:Button ID="button1" Runat=server Text="submit" PostBackUrl="~/NewPage.aspx" />

Thats it! Now when the button is clicked, the page is posted to the "NewPage.aspx".

You can now use the Request.Form to get the value(s) from the previous page.

That really addresses many people's query on the earlier versions.

There is another exciting way to access the previous page's controls which I will write about in my next article.

Cheers and Happy Programming !!!

ASP.NET 2.0 : Accessing controls in Previous Page

Hi,

In my earlier
article, I explained how the PostBackUrl property has made the job of posting the page to a different page easy in Whidbey.

There is a more effective way of accessing the Controls in the previous page. Its using the PreviousPage property of the Page.

Say we have a page Default.aspx with a Textbox "Text1" and a Button "Button1".

There are two ways on how we can access the controls in Default.aspx from another page.

1. Setting the PostBackUrl property of the Button to the New Page, as follows:-

<asp:Button ID="button1" Runat=server Text="submit" PostBackUrl="~/NewPage.aspx" />

Then, in the NewPage.aspx, you can access the TextBox control on Default.aspx as follows:-


public void page_load()
{

TextBox tb = (TextBox)PreviousPage.FindControl("text1");
Response.Write(tb.Text);
}


Note that a new TextBox tb is declared and typecasted using the PreviousPage and FindControl of the ID of the Control in the Previous Page.

2. The other way is the old way of transferring the page to new page using Server.Transfer on the Click Event of the Button in the first page.

But in this case, the PostBackUrl property should not be specified for the Button control.

In the Button declaration in Default.aspx, the code should be

<asp:Button ID="button1" Runat=server Text="submit" OnClick="button1_Click" />

Then, in the codebehind,

void button1_Click(object sender, EventArgs e)
{
Server.Transfer("NewPage.aspx");
}

Still the PreviousPage.FindControl method would work.

This is a wonderful way of accessing the Controls in the Previous Page and I reckon it would be very useful for Developers.

Thanks.

Using SQL Server Stored Procedure for implementing Custom Paging

Hi

All of us would have implemented Paging in our applications.

Paging is particularly useful if you have lots of records to be displayed on a page and you can't get them displayed in one stretch. Say we have 1000 records to be displayed in a page. In this scenario, we cannot show up all the records in a single stretch in the page. Hence we need to implement Paging functionality whereby users can see a set of records and then click on a Button/Link to view the next set of records.

Paging can be implemented in 3 ways viz., Storing all the records at the browser level through XML, session etc., using built-in paging functionalities provided by controls like .NET Datagrid, using SQL Stored Procedures for retrieving set based results.

Out of the above 3, the SQL Method would be the best approach if you are aiming at Custom Paging Mechanism.

But, its a little tricky. Say you have a table which doesn't have an identity column or any sequential data column which you can use to determine the position of each row, then you need to write your procedure in a way that it can take the start values and end values for the set of records to be displayed.

The following procedure is useful to retrieve records in sets for displaying and useful in implementing custom paging.

Let us consider an Employees Table which doesn't have an Identity Column and we want to fetch sets of records based on the set requested for. Consider the following procedure



CREATE PROCEDURE uspPaging
@nStartValue INT,
@nEndValue INT
AS
SET NOCOUNT ON

DECLARE @tblTempData TABLE
(
nID INT IDENTITY,
EmployeeID INT,
LastName VARCHAR(50),
FirstName VARCHAR(50),
SupervisorID NCHAR(5)
)

INSERT INTO @tblTempData
(
EmployeeID,
LastName,
FirstName,
SupervisorID
)
SELECT
EmployeeID,
LastName,
FirstName,
ReportsTo
FROM Employees
ORDER BY
EmployeeID,
FirstName

SELECT EmployeeID,
LastName,
FirstName,
SupervisorID
FROM @tblTempData
WHERE nID BETWEEN @nStartValue AND @nEndValue
ORDER BY
nID ASC


The above procedure will accept 2 parameters @nStartValue and @nEndValue and display the records based on the values. The @tblTempData which we create within this procedure is useful in enforcing the IDENTITY Column which does not exist in the original table.

This procedure can be used when implementing custom paging and can be modified according to the actual requirements.

I welcome your comments.

Cheers and Happy Programming !!!

Button Click Events not firing ? - ASP.NET

Hi,

You may be unable to see the button click events firing on certain machines though it may work in some other machines.

Mostly when you are developing in your local system, the events do work well. But once you move the code to production, the button click events may not fire at all.

This might rise after you install the Microsoft .NET Framework Service Pack 1, which will stop the PostBack Events on client side validation.

To resolve this issue, the aspnet_client folder needs to be reinstalled. To do that type the following from command prompt:-

%windir%\Microsoft.NET\Framework\v1.1.4322\aspnet_regiis.exe -c

This should resolve the issue.

The above command applies to .NET Framework version 1.1. For 1.0, you need to change the version to v1.0.3705 in the above command.

Thanks.

Moving forward to Whidbey .....

Dear All,

Effective from now on, my articles would be focussed on Whidbey, the New Features, Advantages over earlier versions and common problems faced across.

However, I would continue responding to your queries which are posted either as comments or mailed to me directly, regarding your doubts, issues with 1.1 version.

I thank you all for taking the time to read my articles and look forward to your continued support as always.

Cheers and Happy Programming!

What's New in ASP.NET 2.0?

.NET 1.x versions brought revolution in the Programming World and came up with features which were a blessing to developers with most of the plumbing work like Authentication, Sessions, Caching were automatically managed by .NET.

.NET 2.0 version has more to be happy about.

For now I will just list the new features in Whidbey and in the subsequent articles explain about each of the features.

1. CLR Integration with SQL Server

2. New Validation Controls, Validation Groups

3. Improved Caching

4. More than 50 new controls like GridView, DetailsView which offer a seamless ease for displaying data with just a few clicks and configuration.

5. Personalization made easy as never before.

6. Website Administration and User Management made easier than before.

7. WebParts, MasterPages, Themes making Developer's life easier.

8. Extensibility for Mobile Rendering.

9. New features in C# such as Generics, Anonymous Methods.

There are many more other new features which have been discussed in many other resources as well as would be explained in my future articles.

Cheers and Happy Programming!

Building Secure Web Applications using ASP.NET 2.0 ("Whidbey")

In .NET Framework 2.0 ("Whidbey"), ASP.NET has undergone a lot of enhancements. Building secure web applications is one of the aspects that deserves good attention.

There are many new features introduced such as Login Control, Membership API and Personalization API which helps in increasing the productivity of developers.

In .NET 1.1, you can leverage the Forms Authentication to take your anonymous users to the login page. The "Login Page" is your call and you need to code the logic for validating a user against his credentails.

Now, you dont need to do it in 2.0. Microsoft has provided cool features like Login Control which you can just drag and drop and use it for validating your users. It has provided controls for Creating, Modifying, Assigning roles and deletion of users. All of this without you writing single code.

In .NET 1.1, Forms Authentication works on Cookie based scenarios. This has been changed and in 2.0, Forms Authentication woirks for both cookie based and cookieless scenarios. So, your .NET 1.1 code will work very well when moved to 2.0 Framework.

For Cookie based scenarios, it will work the same as earlier and for Cookie Less Scenarios, the Cookie information is encrypted and attached as a querystring value to the URL. Its a long chunk of characters which determine the User's identity and validity.

The Membership API, allows you to manage users effectively, without writing a single line of code. There is also a Website Administration Tool, which comes automatically and from there you can do a website administration for your applications.

In general, the focus has been towards increasing the developer's productivity and automating the plumbing work done which earlier, had to be done manually.

For more information check
ASP.NET 2.0

Cheers and Happy Programming!

Managing Admin / User Accounts for your web applications

No website is complete without a subscription and personalization. Most of the sites provide users to register themselves and have their own accounts, personalized pages etc., On the top of all, it requires an administrator to manage the users and the contents of the site.

The first question that comes when developing such applications is to have separate login pages for users and administrators. I find many people asking question on how to have separate Login Pages for Administrators, Premium Users, Users so that they can give them necessary privileges.

Forms Authentication provides an easy way of restricting anoymous access. However, it doesn't provide the option to have 2 separate login pages for the same authentication setting unless you specify each fodler as a virtual directory and have a web.config with individual authentication tag and login pages. That would be too much of settings and actually not required.

The simple and effective way is to use Role Based Authorization.

I found this
Role-Based Authorization With Forms Authentication a very valuable resource and simple and effective step for users planning to implement Role Based Authorization.

This way you can achieve personalization and privileges based on the user's role.

This article is targetted towards users who would like to do Role Based activities while implementing Forms Authentication.

Comments and Suggestions are welcome.

Building Secure Web Applications - ASP.NET

Security is the matter of the moment now! Building secure web applications is an integral part of today's web development owing to the alarmingly increasing number of hacking threats.

Some of the key things to keep in mind while building secure web applications are

1. Never expose open SQL Statements in your Code.

A statement "select username from users where username='"+ txtUserName.txt +"' and password ='" + txtPassword + "' "

can be easily hacked by a malicious user to read as follows:-

select username from users where username= ' ' OR ' '='' AND password= ''OR ''=''


The above statement will compare "nothing" to "nothing" which will always return True. This will authenticate the user and fetch the first username in the table.

To avoid such type of hacking always use Stored Procedures which are much secured and also good in Performance.


2. Always switch On Custom Errors in the web.config. They are friendly when switched off, only to us and not friendly when viewed by users. Make sure once you go for deployment, to make it either RemoteOnly or On

An ASP.NET Detailed error page can provide the exact error such as, where the application broke and if due to a SQL End problem, straight away can expose the TableName and thus the DB Structure.

Therefore, always use Custom Errors and take the users to a page which tells "Sorry for the Inconvenience..." once an error occurs in your application.

3. Validate all data received as input from the clients. A search textbox which gets search text from the user can very well prove an excellent source for a hacker to embed his SQL Statements, Scripts.

Therefore, ensure you turn the ValidateRequest="True" at the Page directive or do it at the web.config level.

Also, validate if the text entered contains any statement like SELECT, DELETE etc., before processing the information.

4. Never use sa username for your DB Connection String. Its most vulnerable and can be compromised with. Always use a custom Username and Password to access the database from your application.

5. Never store Passwords in your Database as plain text. Hash them or encrypt them to make them secured. Also, sending the password by Email is another source of security threat.

There are many more secure strategies which when followed provide a safe environment for your applications and perhaps can save a Bad Day for you due to hacking.

Cheers and Happy Programming!!

Including Search for your website documents -Part 1

Search is an integral part of any website and particularly if your site has a large number of documents, providing a search functionality would enhance the quality of the website and easy access to documents.

Microsoft Indexing Services can be used effectively to implement search for your websites with less coding and configuration.

Indexing Services scan the Documents and provide an easy way for searching within documents. This built-in feature can be made use of effectively for implementing search functionality.

Configuring Indexing Service to Search within documents

1. Select "My Computer" and right click on it and select "Manage".

2. Expand the "Services and Applications" Node.

3. Select "Indexing Service" and right click on it.

4. Select "New" and then select "Catalog"

5. Enter a name for the Catalog.

6. Enter the location to save the Catalog and then click Ok

7. A new Catalog will be created under the "Indexing Service" Node.

8. Select the New Catalog and then Point to "New" and then
point to "Directory"

9. Point to the path where you store the Documents (Word, Excel, PDF) etc.,

10. Its enough if you point it to the Root of the folder and it would automatically scan the sub-folders.

11. Make sure you select the option Yes for the "Include in Index"

12. Right Click on the Catalog and select Properties

13. Switch to the "Generation" Tab and then select
"Index files with unknown extensions" and "Generate Abstracts" checkboxes.

14. Right Click on the "Indexing Services" Node and select "Stop"

15. The service will be stopped.

16. Now repeat Step 14 and select "Start".

17. The Service is started and the Documents get scanned.

18. It may take sometime to scan all your documents if you have a lot of documents.

19. You can test the Search by selecting the "Query the Catalog" under the Catalog you created.

20. It provides a textbox for entering search text and Button which would display the search results.

21. Now your Indexing Service is ready for searching your documents.

Read
Part 2 for Using the Search Results returned by Indexing Service in your applications.

Including Search for your website documents -Part 2

If you have come to this article without reading the Part 1, please check Part 1

Once you have created the Catalog for your Search, you can use the Catalog for searching.

Using the Catalog in your Application

1. In your Search Page, have a Textbox (TextBox1) and a Button (Button1).

2. In the click event of the Button, put the following code.

string strCatalog = <Put the Name of the Catalog here>;

strQuery = "Select Filename from Scope() where FREETEXT('" + TextBox1.Text + "')";

string connstring = "Provider=MSIDXS.1;Integrated Security .='';Data Source="+ strCatalog;

OleDbConnection objconn = new OleDbConnection(connstring);

OleDbCommand objcmd = new OleDbCommand(strQuery, objconn);

OleDbDataReader objRdr=null;
objconn.Open();
objRdr=objcmd.ExecuteReader();

if(objRdr.HasRows)
{
while(objRdr.Read())
{
docname += objRdr["Filename"].ToString() + ",";
}
docname=docname.Remove(docname.Length-1,1);
}
}


Now "docname" has a comma separated list of file names containing the search text.

You can have an XML File or a Database table with Nodes/Fields - FileName, a Heading and a Description, which you can use to look up for the document name and get the desired results for displaying in your Page.

This way, you can implement search for your website without writing the logic for search.

This article applies to Windows 2000, Windows XP and Windows 2003

Note:
If you would like to search for PDF Files, you need to install the PDF Filter for Indexing Service which helps the Indexing Service in searching within PDF Files. Its a freeware download and can be downloaded from
Here

DataReader, DataAdapter & DataSet - When to use?

ADO.NET offers two central Data Access Components. In this Article we will discuss about their features and when to use what.

ADO.NET provides two central Data Access Components. The excellent thing is that, they are common across all Databases, be it SQL Server or other competitive databases. Its only the namespace to be used, that differs, while using a Database other than SQL Server.

The two Data Access Compnents are:


1. DataSet

2. The .NET data provider, which is a set of components including the Connection, Command, DataReader, and DataAdapter objects.


Its common that the doubt arises on when to use DataReader and DataAdapter, DataSet.

The thumb rule I would suggest is,


1. If your Data access operations is mainly fetching and displaying the records and doesnt involve insert/update/delete statements and other manipulations (forward only, read only) actions, go for the DataReader.


DataReader offers a forward only read stream of access to the records. It is very useful in cases where we just grab the data from the database to display in DataGrid, Label and other Webcontrols.

However, DataReader requires the connection with the database open until its operation is completed.


2. If your Data access operations extend to as simple as an Insert/Update/Delete statement to as complex as using it as a return type from a web service, go for the DataSet. The DataSet has the following advantages.


i. Complex Data type supporting numerous methods such as ReadXML which reads new XML data to form a dataset, WriteXML which provides an XML format of the existing data, etc.,

ii. Works on the disconnected architecutre i.e. The connection doesnt need to be on for the DataSet to perform the manipulations and other actions and is required only at the time of Updating the records to the Database Table.

iii. Provides an In-memory representation of the Data. Can contain one or more DataTable objects that have primary key, foreign key, and constraints between them and can enforce constraints such as unique or be configured to ignore them
iv. Has Individual elements such as DataTable, DataRow and DataColumn to access specific values.

v. While using DataSet and DataAdapter, you don't need to explicitly open the connection. DataAdapter automatically opens and closes the connection as and when required.

Hope it provided some insight into DataReader, DataSet and DataAdapter.

Thanks.

Unable to debug .net 1.1 applications after installing .net framework 2.0

.NET Framework 2.0 (CodeName: Whidbey) is the buzz word around and most of us would have installed the BETA versions to try our hands.

However, after you install .NET Framework 2.0, if you continue to use Visual Studio.NET 2003 you may be unable to debug the applications developed in .NET 1.1. You may receive the error "Unable to start debugging on the webserver..."

The reason is, as a part of installation, the framework registers the 2.0 version with the IIS using the aspnet_regiis.exe -i utility and the script mappings for the virtual directories get updated to 2.0 version.

Therefore, debugging .net 1.1 applications may fail.

The Resolution for this is to change the script mappings in the IIS - virtual directory settings for the application.

Once you install .NET Framework 2.0, you will be able to find the ASP.NET Tab in the Virtual Directory Properties in IIS.

The following steps provide resolution.

1. Type inetmgr from your command prompt

2. Expand the relevant nodes to select your Virtual Directory.

3. Right Click on the virtual directory and select properties.

4. You will be able to see the ASP.NET Tab which has newly come up.

5. Click on the ASP.NET tab.

6. You will be able to see a Dropdownlist with .NET 2.0 and .NET 1.1 versions listed.

7. Select the 1.1 Version and click Apply and then click ok

Now you will be able to debug your applications developed in .NET 1.1 using Visual Studio.NET 2003.

There are other errors that you may receive when running .net 1.1 applications after installing .NET 2.0. which I will explain in next article.

Happy Programming!

Fragment Caching - Caching parts of a Page

Caching is one of the recommended techniques to improve the performance of web applications by avoiding repeated requests to the server.

It serves the purpose for faster response as well as reducing the load to the Server.

Output caching can be enabled easily by just including the following code in the Top of the aspx page

<%@ OutputCache Duration="1200" VaryByParam="None" %>

This would result in the whole page being cached.

However, there will be situations where we would like to cache only sections of page rather than the whole page. There may be sections of the page where the information gets updated every second or so and these sections should not cached.

This can be implemented in ASP.NET using Fragment Caching. Fragment Caching is the technique by which we can cache a sections of the page instead of caching the whole page.

This is accomplished by dividing the pages into usercontrols and caching the individual usercontrols.

Say we have a page which has 5 sections. We can split the static sections into usercontrols and cache them such that only that portion of the page is cached..

The syntax for fragment caching is similar to output caching

<%@ OutputCache Duration="1200" VaryByControl="None" %>

We can therefore cache only portions of the page and avoid the whole page being cached.

Note the VaryByControl attribute. It is unique to user controls caching and we can specify the ID of a webcontrol (ex. DropDownList) to invalidate the cache if the control's selection / property is changed.

Caching has been improved a lot with the .NET 2.0 version which is scheduled to be released sometime during early 2005.

Output Caching based on File Dependency

In this article we will see how we can add output caching to our aspx pages and invalidate the cache based on change of a flat file like xml, txt etc.,

Basically, caching serves the purpose for serving repeated request from the cache such that the number of requests to the Server and the time taken can be drastically reduced. Say, there are about 100 requests for a page in regular intervals. At that time caching would be very useful since it will serve all the requests from the cache and reducing the load for the server.

In our aspx pages, we can enable caching simply by including the following tag in the top of the page.

<%@ OutputCache Duration="1200" VaryByParam="None" %>

The Duration specifies the number of seconds the cache will be valid. After that duration, the cache will expire.

Supposing we have some data file like xml or text file from which we populate the aspx page. Then, if we want to invalidate the cache as soon as the file is edited, it can be accomplished by using the FileDependency Method.

Response.AddFileDependency(Server.MapPath(physical root path of the file))

The above line of code needs to reside in the codebehind of the aspx page or as inline script within the page.

This would ensure that the page is not served from cache if the dependant file has been changed.

We will look into more dependencies such as Database etc., in forthcoming articles.

SmartNavigation to maintain scroll position across postbacks

Smart navigation is deprecated in Microsoft ASP.NET 2.0 and is no longer supported by Microsoft Product Support Services. This article describes how to implement the smart navigation features in ASP.NET 2.0.

For more information check http://support.microsoft.com/kb/913721

Thanks to Deepak for posting this in the comments. 

This article describes about using the Smart Navigation property to maintain the scroll position of pages across postbacks.

All of us know that asp.net controls postback to the server and hence the page is reloaded everytime an event is triggered.

Supposing we have a very long page with lots of controls. A user is in the middle of the page and triggers an event (say click event), which causes the page to postback. Then the page will be reloaded and the position would go to the top.

This could be particularly annoying if the user has to scroll down long and repetitively.

To avoid this, ASP.NET provides the SmartNavigation property for the page which takes care of the scroll position.

SmartNavigation also avoids the flickering of the page when the page is reloaded.

It can be enabled by simply setting its value to true in the page directive, as follows:-

<%Page smartNavigation="True" %>

Alternatively, it can be specified as a global setting in the web.config as follows:-

<configuration>
<system.web>
<pages smartNavigation="true"/>
</system.web>
</configuration>

This would apply for all the pages that fall under the web.config's settings.

This is a wonderful mechanism particularly if you have lengthy pages and repetitive server side interactions.

This works only for Internet Explorer browsers and for Netscape, it is simply turned off automatically.

Another issue that may arise is when using javascript and dhtml scripts as they will not be rendered again while using smartnavigation.

Cheers !!!

You may receive the Error Message "Server Error in '/application name' Application" while browsing an asp.net application

You may receive the following error message while browsing an asp.net application


"Server Error in '/application name' Application
--------------------------------------------------------------------------------

Runtime Error
Description: An application error occurred on the server. The current custom error settings for this application prevent the details of the application error from being viewed remotely (for security reasons). It could, however, be viewed by browsers running on the local server machine.

Details: To enable the details of this specific error message to be viewable on remote machines, please create a tag within a "web.config" configuration file located in the root directory of the current web application. This tag should then have its "mode" attribute set to "Off". "



This error might occur due to two scenarios.

1. There is an error in the application's logic with the inputformat, Type etc., and you have set the Custom Error Mode in the web.config to "On" and not specified a default redirect error page.

2. The web.config file is not well formed or having invalid characters and the application is not able to pick up the settings from the same.

Solution

1. Set the custom error mode to "Off" to view the error. After rectifying it and before deployment, change it to "On" and specify a default error page, as follows:-

<customErrors defaultRedirect="ErrorPage.aspx" mode="On">

</customErrors>

such that your users will not be able to see the actual error and get your friendly error page where you can politely say "An error has occured! Sorry for the inconvenience ..." .

2. If the above solution is not working (i.e. even after setting the custom error mode to On, the same "Server Error" occurs, then the likely chance is that your web.config file is not well formed and has invalid characters etc.,

To resolve, it copy paste the contents of the file to a notepad, save it as an xml file and try to browse the xml file in the browser. If the xml file is unable to be rendered by the browser and throws error, then you can find the place where the tags are not well formed or invalid character(s) exist and rectify them.

Things worth noting is Web.config is case sensitive and even trailing / leading spaces can cause the above error.

This article applies to .NET - ASP.NET 1.0, 1.1 Versions.

Handling Page Load Events and PostBack Issues

A number of queries, articles from developers rise on this issue.

When you bind a dropdownlist or other databound controls to a datasource during the page_load event, the process is triggered each time the page is loaded.

In the followign code, we call a method which will populate a dropdownlist on the Page_Load Event:-

private void Page_Load(object sender, System.EventArgs e)
{
BindDropDownList1();
}

We select an item in the dropdownlist after the page has loaded and the list has been populated.

Then, we have button and on its click event, we want the selected item in the dropdownlist to be displayed.

Guess what you will get as selected item no matter what you select from the dropdownlist? The first item or the default item such as "Select an option".

The issue is due to the postback that occurs when the button is clicked. ASP.NET server controls are posted back to the server for all events and hence, the page will be reloaded - thereby the dropdownlist again populated and the selected item would be the first default item.

To avoid this, we must put the dropdownlist populating code within the IsPostBack condition, as follows:-

private void Page_Load(object sender, System.EventArgs e)
{
if(!IsPostBack)
{
BindDropDownList1();
}
}

This would ensure that the dropdownlist is not repopulated during each postback and if you try to get the selected item, you will get the correct selected item even though the page postbacks.

This is applicable to .NET version 1.0, 1.1 since in .NET 2.0 (CodeName: Whidbey), this has been handled automatically to check postbacks and normal page_loads.

Forms Authentication - Redirecting users to a Page other than Default.aspx

In this article I will explain how to redirect users to a specific page rather than the generic default.aspx upon successful authentication of the user.

While using ASP.NET Forms authentication, if we try to access a protected page, the user would be taken to the login.aspx page with the ReturnUrl parameter having the path for the originally requested page.

Once, the user's credentials are verified, the RedirectFromLoginPage method can be used to take the user back to the originally requested page.

However, if there is no specified ReturnUrl, then FormsAuthentication by default takes the user to the default.aspx page upon successful authentication.

If we do not have a default.aspx page or we want to take the users to our custom page etc., then we can use the Setauthcookie method to set the cookie and then redirect users to our desired page. The following code establishes the same.

// Once the user's entered credentials are verified //
if(Request.Params["ReturnUrl"] != null)
{
FormsAuthentication.RedirectFromLoginPage(txtUserName.text, false);
}
else
{
FormsAuthentication.SetAuthcookie(txtUserName.text, false);
Response.Redirect("CustomPage.aspx");
}

The above code first verifies whether there is any ReturnUrl parameter such that if exists, it should take to the originally requested page.

Else, it sets the authcookie and then redirects user to a custom page.

The txtUserName is the ID of the textbox which is used to capture the username.

This article applies to ASP.NET 1.0 & 1.1 Versions.

You may receive the error "Parser Error Message: Could not load type 'WebApplication1.Global'." when browsing an asp.net page

You may receive the following error when browsing an asp.net application.


Parser Error Message: Could not load type 'WebApplication1.Global'.

Source Error:

Line 1: <%@ Application Codebehind="Global.asax.cs" Inherits="'WebApplication1.Global'" %>

This error occurs when you create a new web application in asp.net using visual studio.net and without compiling the application, you try to browse a page in the application.

This occurs because of the Application DLL not having been formed.

asp.net will look in the Global Assembly Cache, and then in the application's local bin directory. If it can't find the class with the name you specified then it won't load. When you do a codebehind file in Visual studio, you are writing a base class for your aspx file to inherit from - the HTML template you write in the aspx is inlined into the dynamically generated subclass's Render method.

Even if you don't put any code in your page, you still need to compile it as long as you put the Inherts Webappname.Global in your Page directive.

To resolve this, Built the application using Ctrl + Shift + B or use F5 to build the application and then try to browse the application. The error will be resolved.

This is applicable to .NET 1.0, 1.1 versions - Visual Studio.NET


You may receive the error "It is an error to use a section registered as allowDefinition='MachineToApplication' beyond application level" in asp.net

You may get this error when trying to browse an asp.net application.

The debug information shows that "This error can be caused by a virtual directory not being configured as an application in IIS."

However, this error occurs primarily out of 2 scenarios.

1. When you create an new web application using visual studio.net, it automatically creates the virtual directory and configures it as an application.
However, if you manually create the virtual directory and it is not configured as an application, then you will not be able to browse the application and
may get the above error. The debug information you get as mentioned above, is applicable to this scenario.

To resolve it, Right Click on the virtual directory - select properties and then click on "Create" next to the "Application" Label and the textbox. It will
automatically create the "application" using the virtual directory's name. Now the application can be accessed.


2. When you have sub-directories in your application, you can have web.config file for the sub-directory. However, there are certain properties which cannot
be set in the web.config of the sub-directory such as authentication, session state (you may see that the error message shows the line number where the
authentication or sessionstate is declared in the web.config of the sub-directory). The reason is, these settings cannot be overridden at the sub-directory level
unless the sub-directory is also configured as an application (as mentioned in the above point).

Mostly we have the practice of adding web.config in the sub-directory if we want to protect access to the sub-directory files (say, the directory is admin and we
wish to protect the admin pages from unathorized users).

But actually, this can be achieved in the web.config at the application's root level itself, by specifing the location path tags and authorization, as follows:-

<location path="Admin">
<system.web>
<authorization>
<allow roles="administrators" />
<deny users="*" />
</authorization>
</system.web>
</location>

However, if you wish to have a web.config at the sub-directory level and protect the sub-directory, you can just specify the Authorization mode as follows:-

<configuration>
<system.web>
<authorization>
<allow roles="administrators" />
<deny users="*" />
</authorization>
</system.web>
</configuration>

Thus you can protect the sub-directory from unauthorized access.

Cheers.

The Cool asp:xml control for displaying xml data.

How many of us are aware that we can use the <asp:xml> server control to just specify the xml file and the xslt or other stylesheet file and then without a single line of code, .net does the transformation for rendering in an aspx page?

For the benefit of those who are not aware, the following is the code for accomplishing the same:-

<asp:Xml id="Xml1" runat="server" DocumentSource="file path to xml file" TransformSource="file path to xslt file">

Put the above code in the aspx page as you would normally declare other server controls like button, label etc., and it will load the document, apply the stylesheet and render it for you, in the aspx page. All done without a single line of additional code.

You can assign the DocumentSource and TransformSource from the codebehind as well like other server controls.

If you are using a DataSet and want to assign the xml from the dataset, well you can use the DocumentContent property of the <asp:xml> control to specify the xml format as follows:-

Xml1.DocumentContent = DataSet1.GetXml();

where Xml1 is the id of the <asp:xml> control.

Cheers.

Selecting Distinct Values using XPath Expression

Hi,

XPath is one of the flexible standard for querying an xml document.

Let us consider the following CD xml as example:-

<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
<cd country="USA">
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<price>10.90</price>
</cd>
<cd country="UK">
<title>Hide your heart</title>
<artist>Bonnie Tyler</artist>
<price>9.90</price>
</cd>
<cd country="USA">
<title>Greatest Hits</title>
<artist>Dolly Parton</artist>
<price>9.90</price>
</cd>
<cd country="UK">
<title>Hide your heart</title>
<artist>Bonnie Tyler</artist>
<price>9.90</price>
</cd>
</catalog>

In the above xml, if we would like to get distinct country names, then we can make use of the preceding-sibling property to check for any
existence of the country name so as to filter and show only distinct country names.

/catalog/cd[not(@country=preceding-sibling::cd/@country)]/@country

The above expression would select only distinct country names i.e. UK and USA only once each.

Cheers.

Assigning the text value for a Password Textbox

Hi,

Setting the text property for a textbox with textmode=single and multiline is pretty straight forward by giving

TextBox1.Text = "The text we want to set";

However, if we set the Textmode property to Password, then we cannot simply set the text using the TextBox.text.

In practical scenarios, we may not want to set the password for obvious reasons that password is one which we retrieve from the user and it shoult not be set.

Also, even if we set some password, the user cannot read it as it is just a sequence of dots.

If, for however, due to specific reasons, we need to set the password, then we can do the same by using the following code:-

txtpasswd.Attributes.Add("value", "the password we wish to set");

Or, if you are assigning the password from the database you can use a DataReader in place of the actual password, as follows :

txtpasswd.Attributes.Add("value", objRdr["Password"].ToString());

Cheers.

Setting Role cookie at the Application Level in Role Based Authorization - Forms Authentication

Hi,

When using Role Based Authorization, we can set the Roles of a user at the application level by specifying it in the Global.asax's Application_AuthenticateRequest method.

As soon as a user is authenticated, it will fetch his roles from the database and assign it to him so that we can use the User.IsInRole("RoleName") to check his role and perform actions based on the same.

You can find many resources on the above topic on how to set the roles. However, one disadvantage is that on every page you check the Role, the DB call is made which might affect the performance of the application.

To resolve that we can set the role cookie manually through code so that it doesnt make the DB call for every request.

The following code segment provides the code for the total operation.


In the Global.asax's code behind file, locate the following method and put the code inside as follows:-



protected void Application_AuthenticateRequest(Object sender, EventArgs e)

{

AssignRolesToUser();

}




Then place the following code segment.





private void AssignRolesToUser()

{

if (Context.Request.IsAuthenticated)

{

// Retrieve user's identity from context user

FormsIdentity ident = (FormsIdentity) Context.User.Identity;



// Retrieve roles from the authentication ticket userdata field

string[] roles = ident.Ticket.UserData.Split('|');



// If we didn't load the roles before, go to the DB

if (roles[0].Length == 0)

{

// Fetch roles from the database.

roles = FetchRoles();



// Store roles inside the Forms ticket.

FormsAuthenticationTicket newticket = new FormsAuthenticationTicket(

ident.Ticket.Version,

ident.Ticket.Name,

ident.Ticket.IssueDate,

ident.Ticket.Expiration,

ident.Ticket.IsPersistent,

String.Join("|", roles),

ident.Ticket.CookiePath);



// Create the cookie.

HttpCookie authCookie = new HttpCookie(

FormsAuthentication.FormsCookieName,

FormsAuthentication.Encrypt(newticket));

authCookie.Path = FormsAuthentication.FormsCookiePath + "; HttpOnly; noScriptAccess";

authCookie.Secure = FormsAuthentication.RequireSSL;



if (newticket.IsPersistent)

authCookie.Expires = newticket.Expiration;



Context.Response.Cookies.Add(authCookie);

}



// Create principal and attach to user

Context.User = new System.Security.Principal.GenericPrincipal(ident, roles);

}

}







private string[] FetchRoles()

{

// Fetch roles from the database somehow.

ArrayList roleList = new ArrayList();

SqlDataReader objRdr=null;



SqlConnection objCon = new SqlConnection("Your connection string here);

SqlCommand objCmd = new SqlCommand("spRoles", objCon);

objCmd.CommandType = CommandType.StoredProcedure;

objCmd.Parameters.Add("@Username", User.Identity.Name.ToString());

try

{

objCon.Open();

objRdr = objCmd.ExecuteReader();

if(objRdr.HasRows)

{

while(objRdr.Read())

{

roleList.Add(objRdr["RoleName"].ToString());

}

}

objRdr.Close();

}

catch

{

return null;

}

finally

{

objCon.Close();

objCon.Dispose();

}

return (string[])roleList.ToArray (typeof (string));

}






The procedure spRoles will fetch the roles based on the UserName which is passed as a parameter.

The code for the procedure is as below:-



CREATE PROCEDURE spRoles

(

@Username varchar(50)

)

AS



SELECT G.Name

FROM Roles R

INNER JOIN Groups G ON

R.GroupID = G.GroupID

INNER JOIN Users U ON

R.UserID = U.UserID AND U.Username = @Username




In the above procedure I have used three sample tables Users, Groups and Roles

Users - will contain UserID, UserName and password
Groups - will contain GroupID and Name i.e. Admin, Moderator, User
Roles - will contain the UserID and their GroupID i.e. group they are assigned to.


Once you set the above Roles, thereafter in your pages, you can just use

if(Context.User.IsInRole("RoleName"))
{
// do something
}


Queries, Comments and Suggestions are welcome.

Thanks.

ASP.NET Application Deployment - Performance Enhancement

Hi,

Before deploying ASP.NET applications, carrying out the following steps would ensure the enhanced performance of the application:-

1. In Visual Studio.NET, select the Mode as Release (the drop down in the top center next to the > start icon) and then Build the Application. This would enhance the performance as in the DEBUG mode, the performance would be slow since the DEBUG information has to be written in the pdb file. (If you build in Release mode, the PDB file is not generated). The resultant DLL would give an enhanced performance.

2. In the web.config file, set the debug attribute to false, as below:-

<compilation
defaultLanguage="c#"
debug="false"/>

This would increase the performance greatly.

3. Remove unnecessary Exception handling as they consume the resources heavily.

Cheers.

ASP.NET Deployment - Files to be Deployed

This article refers to ASP.NET v1.x version.  For updated version for ASP.NET 2.0, please check http://geekswithblogs.net/ranganh/archive/2007/07/31/114320.aspx

Many of us have this question of what are the files we need to publish when using FTP to move files to production server, for deploying an ASP.NET Web application.

The question obviously arises because when we use Visual Studio.NET to create a web application, there are many files created such AssemblyInfo.cs, Global.asax, Web.config, Proj file, codebehind files, resx files for each aspx page, etc.,

This article helps in understanding what are the files and why they are required for deployment.


1. ASPX files - These files are required as they hold the design as well as the controls declarations and these are the pages accessible by the users.

2. ASCX files - Usercontrols which form part of the pages.

3. BIN Folder - The BIN folder holds the key for an asp.net application. The DLL for the application lies within this folder and all the application logic you write in the codebehind files (.cs or .vb) are built into this DLL. The BIN folder has to be in the root of the directory and the DLL should be available within the BIN folder.

4. Web.config file - This is the configuration file for the application. Many settings such as Authentication, Session State, Authorization, Global Variables and other things can be set in this file. The advantage is that this file is an XML file and therefore doesnt require a compilation of the DLL after editing the file. It is advisable to store many configurable things like connection string, Database name, etc., in this file i.e. so that after deployment, changing these, doesnt require recompilation.

5. Other static files like CSS, JPG, GIF, XML, XSL Files also need to be published.

The following are the list of files NOT required to be published.

1. Codebehind files - .cs if c# and .vb if vb.net
2. RESX files
3. Proj file
4. Webinfo file
5. AssemblyInfo.cs or AssemblyInfo.vb

Cheers.

Denying access to view XML, XSL Files

Hi,

We all know that XML is a standard format most of the sites use for managing content. Most of the sites use xml for storing data and use XSL and other stylesheets for displaying the data.

The XML files can be browsed as well as a standard web page and the XML format is rendered in the browser.

However, if we would like to deny users from viewing our xml format and data by directly browsing the xml file, we can use the HTTP Handlers effectively.

The HTTP Handlers provide the flexibility to handle different extensions on how they are rendered and to deny access to them.

To deny access to an xml or other static file, the following steps would help

1. Add the following code to your web.config file within the <system.web> & </system.web> tags.

<httpHandlers>
<add verb="*" path="*.xml" type="System.Web.HttpForbiddenHandler"/>
</httpHandlers>

2. In the IIS, right click on your virtual directory and then click properties.

3. Click on the Configuration Button.

4. There will be a list of extensions and the executable paths.

5. Click "Add" and then in the dialog box which opens, browse the location
%windir%\Microsoft.NET\Framework\v1.1.4322\aspnet_isapi.dll in the "Executable" box

6. Enter the extension i.e. .xml for xml files in the textbox "Extension"

7. In the "Verbs" radio button, click on "Limit to" and enter "GET,HEAD,POST,DEBUG"

8. Cick "Ok" then click "Apply" and then "Ok" two times.

9. Now if you try to browse the xml file within that application, you will a "This type of page is not served".

10. The same can be accomplished at the system level by adding the Handlers in the machine.config's http handler section. That will apply for all the asp.net applications running on that system.

11. This method is useful when we want to restrict access for certain static files like the above example.

Comments are welcome.

"Page cannot be found" when browsing aspx pages in Windows Server 2003 with IIS 6.0

Hi,

You may get a Page cannot be found message when you browse aspx pages in a Windows Server 2003 environment.

That is because in Windows 2003, all the webservice extensions are "Prohibited" by default to ensure security.

To resolve this, do the following steps:-

1. From your Run command, type inetmgr and press enter.
2. Expand the appropriate nodes in the IIS to locate the "Webservice Extensions" Node
3. Click on the same.
4. You will find a list of "prohibited" extensions in the right.
5. Click on ASP.NET and "allow" it

That should resolve this issue.

This article applies for Windows Server 2003, IIS 6.0 environment.

Redirecting users to Custom "Not Authorized" page while implementing Role Based Authorization.

Hi,

When using Forms Authentication with Role Based Authorization, we can restrict users based on their role for different directories/pages.

However, if an user who doesn't have authorization to view a page, tries to view the same, he will be directed to the Login page with a ReturnUrl parameter, despite the user already being logged in.

That doesnt give any idea to the user as to why he is getting directed to the same login page while he has already logged in and doesnt give him the message that he is not an authorized person to view that page.

However, we would like to take them to a Custom "You are not authorized to view this section" page.

This can be achieved by a little tweaking of code in the login page.

In the Page_Load event of the Login page, you can check if the User is Authenticated and if the querystring for ReturnURL is not null. Then we can get an idea that the user has tried to view an unauthorized section and has been directed to login page.

So if both the above conditions are true, you can safely response.redirect them to your custom "Not authorized" page.

The code for the same is as follows:-

if(User.Identity.IsAuthenticated && Request.QueryString["ReturnUrl"] != null)
{
Response.Redirect("NotAuthorized.aspx");
}

The above is not the only solution and this can be handled using custom HTTP handler events. However, I found this to be a simpler, quicker solution with much less coding effort.

"Parser Error Message: Access is denied: Source Error: Line 198: "

Hi,

One of the stunning errors you may get while trying to browse your page is

Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.

Parser Error Message: Access is denied: 'MyWebApp'.

Source Error:

Line 198: <add assembly="*"/>

As you can see the debug information is quite unclear and it would leave no trace of idea as to where the problem is.

The actual problem is because of the Microsoft Indexing Services which scans the Temporary ASP.NET Files and while doing so, the system puts a lock on the same.

To resolve this, the following steps need to be carried out:-

1. Start - Settings - Control Panel - Administrative Tools - Computer mangement.

2. Expand the services and applications node and select the Indexing service node.

3. Expand the Indexing Service Node and then select and expand the System Node.

4. Right click on Directories and select new directory. browse the path to the temporary asp.net files c:\winnt\microsoft.net\framework\v1.1.4322\.

5. Select the temporary asp.net files. give ok and then select the "NO" in the Include in index radiobutton.

6. give ok and then stop and start the indexing service.

this should solve the problem.

How to get the SelectedValue of all List controls that are present in a Page

This article describes how to get the selected values of all list controls present in a page using just a single method.

One of the common requirements I see as required by developers is to create a Questionarre which consists of many questions with Radio Button Options as answers.

To loop through all the radiobuttons and get the selected value of them, its tedious if you write code for each and every radiobutton.

The following code accomplishes the task.

private void Button1_Click(object sender, System.EventArgs e)

{



foreach(System.Web.UI.Control ctl in this.Page.Controls)

{

LoopAllControls(ctl);

}

}


public void LoopAllControls(System.Web.UI.Control oControl)

{

foreach(System.Web.UI.Control frmControl in oControl.Controls)

{

if(frmControl.GetType().ToString()=="System.Web.UI.WebControls.RadioButtonList")

{

RadioButtonList rList=new RadioButtonList();

rList=(RadioButtonList)frmControl;

Response.Write(rList.SelectedValue);

}

if(frmControl.HasControls())

{

LoopAllControls(frmControl);

}

}

}


The above code just Response.Writes the selected values of the radio button lists. You can have as many radio button lists as you want in the page. The above code would work for the same.

However, if you want to find some total or store, you can use a variable to get each value.

Hope it helps.

Unable to Start Debugging on the Webserver. The Project is not configured to debug

Hi,

You get this error "Unable to start debugging on the webserver. the project is not configured for debugging" occasionally when your aspnet account doesnt have debug permissions.

This can happen, if the vs.net installation was not made properly or some reasons when the aspnet account fails to have the necessary rights.

To resolve this, re-register the aspnet account with the IIS, by typing the following command from the command prompt:-

%windir%\Microsoft.NET\Framework\v1.1.4322\aspnet_regiis.exe -i

Note: Change the v1.1.4322 to v1.0.3705 if you are using .net 1.0 version. 
This should resolve the problem.

I have been receiving various queries regarding different versions of this error “Unable to start debugging...“.  This error appears due to many reasons other than the above mentioned.

For a complete list of solutions, please check http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_vstechart/html/vsdebug.asp

Excluding Registration Page from Forms Authentication

All of us would agree that ASP.NET Forms Authentication is very useful and effective in implementing a Form based authentication for websites.

With the methods and properties it provides, it becomes quite easy for us to implement authentication (contrary to the classic asp, where one has to write chunk of codes individually in all the pages)

Well, all of us would have a login.aspx which would be the default login page for the app and any unauthorised request for other pages, would redirect to the Login Page.

However, we would like to have a Registration page, in case the user is not a registered user to which he can go from the login page. So, we provie a link called "Register" so that new users can register.

Since we have implemented Forms Authentication for the website, even the Register.aspx page would require logging in. To avoid the Registration page from falling under authentication, a little tweaking is required in the web.config file.

In the web.config file where we declare the authentication mode=forms, the following set of tags need to be there

<location path="Register.aspx">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>


This would make the Register.aspx page available to anonymous users.

Same way we can also provide for Forgot Password page, if any.

Happy Programming!

Securing PDFs, DOCs, in Forms Authentication

Please note this article refers to ASP.NET v 1.x versions.  In ASP.NET 2.0, this is taken care automatically.

When using Forms Authentication, any anonymous request for secured pages will be redirected to Login page.

However, when the request is for static file types like Word, PDF etc., the redirection won't happen and the content will be served.

There are many instances when we want to secure our DOCs, PDFs to only authenticated users.

The problem is that, these static files are handled by the IIS and since we set anonymous authentication in IIS, they won't prompt for username and password.

To handle this, we need to force asp.net to handle these file types.

This can be achieved by the following steps.

1. Open the IIS Control Panel (inetmgr from command prompt)
2. Expand the appropriate nodes and select the Virtual Directory of the application which needs authentication.
3. Right click on the Virtual Directory and select Properties.
4. Click the Configuration Tab
5. A dialog box appears with the list of file extensions.
6. Click Add and a dialog appears asking for URL with browse button and a textbox where the extension type to be entered.
7. Click on the Browse button and select the the following path
%windir%\Microsoft.NET\Framework\v1.1.4322\aspnet_isapi.dll
8. Enter the extension type in the textbox such as .pdf, .doc etc.,
9. Select the "Limit to" radio button and Put the same properties as like for aspx files i.e. GET, HEAD, POST, DEBUG
10. Click ok - ok. Repeat the same for other file extension types which you want to secure.

Now the above extensions will be served by asp.net and hence they will be authenticated, provided you are securing the folder, directory which contains these files to be secured.

Hope it helps.

Selected Item in Dropdownlist in an Usercontrol

Hi,

A Common requirement we have would be to have a Dropdownlist of items which would be common across all the pages (top navigation or in the left navigation).

Retrieving the selected item in a dropdownlist which resides in the same page, is pretty straight forward dropdownlist1.selecteditem.value.

However, when it is in a usercontrol, its pretty difficult to retrieve it since you will get the "Object Reference not set to an instance" error if you try the normal method. Even if you create an instance of the usercontrol and try to access its dropdownlist, you will get the above error.

The following code demonstrates how to overcome this problem.

UserControl objCtrl = ((UserControl)(FindControl("Id of the Usercontrol as declared in the container page")));

DropDownList ddl = ((DropDownList)(objCtrl.FindControl("Id of the Dropdownlist control in the usercontrol")));

Response.Write(ddl.SelectedItem.Value);

Thats it and you can access the value.

Cheers and Happy Programming!

"Unable to find script library '/aspnet_client/system-web/1-1-4322/webvalidation.js'"

Hi,

One of the common errors that may occur when publishing your application to live server is that you may get the following error.

Unable to find script library '/aspnet_client/system-web/1-1-4322/webvalidation.js'try placing this file manually or reinstall by running 'aspnet-regiis-c'

This would occur particularly if you are using validation controls in your application.

The aspnet_client folder contains the WebUIValidation.js which is required to handle the asp.net validation controls.

If the aspnet_client folder is missing in the IIS virtual directory listing you may encounter the above error. to resolve this, you may need to run the following from command prompt

%windir%\Microsoft.NET\Framework\v1.1.4322\aspnet_regiis -c

This will install the aspnet_client folder to the default virtual directory website.

Further, if you are using a sub-virtual directory you need to have this aspnet_client folder in your root directory as well.

To do this, you can manually copy the folder to your root directory.

This would help in solving the error.

Filling a Dropdownlist dynamically, with Validation Control Enforced

Hi,

Many of the people new to ASP.Net would be excited about the Dropdownlist control which is very useful in appliactions. Howevever, much as it is easy to add items to the dropdownlist with static asp:ListItem tags, adding values to the dropdownlist dynamically is a bit complex and involves a little bit of coding.

Also, one of the common issues faced by developers is how to enforce Required Field Validator for Dropdownlist.

Herebelow is the code snippet for a Dropdownlist with validator and dynamically filling the same from Database. It uses an imaginary table tblCountry which has the fields CountryId, CountryName. The select statement is pretty straightforward and can be tweaked accordingly to one's requirement.

ASPX Code for declaring the control with Required Field Validator
===================================================================

asp:dropdownlist id="ddlCountry" runat="server" DataTextField="CountryName" DataValueField="CountryId"

asp:requiredfieldvalidator id="CountryValidator" Runat="server" ControlToValidate="ddlCountry"
ErrorMessage="Please select your Country" InitialValue="0"

C# Code for populating the dropdownlist dynamically from the database
=====================================================================

public void Bind_ddlCountry()
{
SqlConnection objcon = new SqlConnection("Connectionstring");
SqlCommand objcmd;
SqlDataReader objRdr;
string selstr;
selstr = "SELECT CountryId, CountryName FROM tblCountry";
objCmd = new SqlCommand(selstr, objCon);
try
{
objCon.Open();
objRdr = objCmd.ExecuteReader();

DataTable dt = new DataTable();
DataRow dr;
dt.Columns.Add(new DataColumn("CountryName", typeof(string)));
dt.Columns.Add(new DataColumn("CountryId", typeof(string)));
dr = dt.NewRow();
dr["CountryName"] = "Choose One";
dr["CountryId"] = 0;
dt.Rows.Add(dr);
while(objRdr.Read())
{
dr = dt.NewRow();
dr["CountryName"] = objRdr["CountryName"];
dr["CountryId"] = objRdr["CountryId"];
dt.Rows.Add(dr);
}
ddlCountry.DataSource = dt;
ddlCountry.DataTextField = "CountryName";
ddlCountry.DataValueField = "CountryId";
ddlCountry.DataBind();
objRdr.Close();
}
catch(Exception ex)
{
Response.Write(ex.Message);
}
finally
{
objCon.Close();
objCon.Dispose();
objCmd.Dispose();
}
}

Hope it helps.

"Visual Studio .NET has detected that the specified Web server is not running ASP.NET version 1.1. You will be unable to run ASP.NET Web applications" - Updated

A very common but weird error we get when trying to create / open asp.net applications using visual studio.net is "Visual Studio .NET has detected that the specified Web Server is not running ASP.NET version 1.1. You will be unable to run ASP.NET Web applications or services." 
 
This error occurs primarily due to following reasons
 
1. IIS installed after Visual Studio .NET is installed.
2. ASPNET Account removed / doesnt have sufficient permissions.
3. Script Mappings not updated in the IIS
4. Proxy Settings

Resolution 1
 
The resolution for the first 3 reasons is simple. Reinstall

Version Numbers for other versions

.NET Framework 2.0 - v2.0.50727 for Visual Studio 2005 (Released Version)

.NET Framework 1.0 - v1.0.3705 for Visual Studio .NET 2002

Resolution 2

The other resolution for proxy settings is as follows:-

1. Open Internet Explorer

2. Go to Tools - Internet Options - Connections - LAN Settings - Advanced

3. Under “Do not use Proxy server for addresses beginning with“, enter localhost or your local IP starting number in the Text Area.

4. Clik Ok 3 times to exit.

5. Restart Visual Studio .NET and you should be able to create ASP.NET Applications.

Feel free to write back or post alternative solutions in the comments section, if the above solutions doesnt solve the issue.

Thanks.

Cheers,

Harish.

Note: I thank all of you who have expressed their gratitude and thanks for this solution.  I have updated this article with the second set of steps involving proxy settings.

 

the aspnet user account.  To do that, type the following from your command prompt:-
 
%windir%\Microsoft.NET\Framework\v1.1.4322\aspnet_regiis.exe -i

the above is based on .net 1.1 version (Visual Studio .NET 2003). For other versions, just change the version number.