Tuesday, July 8, 2014

ASP.NET Response.Redirect & Server.Transfer: Differences & Usage Scenarios.

Introduction:

In ASP.NET there are two methods to redirect a user from one page to another page. One is using Response.Redirect() and other using Server.Transfer(). Even though both these methods do the same task, there is some difference between them and are meant to be used in different scenarios.

Both Response.Redirect and Server.Transfer works fine and redirects the user to the desired page but technically speaking the way they do the transfer / redirect is quiet different.

In this brief article we can have a look at how these methods differ and in which scenarios we should use each of them.

Response.Redirect Method:

Suppose you have two pages in your ASP.NET application say Page1.aspx and Page2.aspx. When you use Response.Redirect following are the sequence of actions that happen behind the scene to redirect the user from Page1.aspx to Page2.aspx.
  1. When the Page1.aspx page is accessed, the corresponding Page Life Cycle events get executed and in between the execution, the Response.Redirect happens.
  2. Immediately the server sends a HTTP 302 command to the browser (instructing the browser to initiate a GET request to Page2.aspx page).
  3. Browser interprets the 302 command and sends a GET request for Page2.aspx page. So here the page transfer is actually done by the browser.
In this case you can see that the URL in the browser address bar got changed from yourdomain.com/Page1.aspx to yourdomain.com/Page2.aspx. When you use  Response.Redirect method, the previous page is removed from the server memory and the new page is loaded there. In this scenario you can't get context data on another page and if you try to access the Context.Item collection you get an exception object as null since the previous page doesn't exist in server memory.

This method can be used for both .aspx and HTML pages and this method should only be used if you want to redirect the user to an external page.

Server.Transfer Method:

When you use Server.Transfer following are the sequence of events for navigation:
  1. Server starts processing Page1.aspx page and the corresponding Page Life Cycle events are executed. But before the Page Life Cycle is completed Server.Transfer happens to Page2.aspx page.
  2. Here the page transfer is actually done by the server. So Page2.aspx page object is created, full page life cycle is executed and output HTML response is then sent to the browser.

In this case you can see that the URL in the browser address bar remains the same even after loading Page2.aspx page. Here the previous page also exists in server memory and so you can get data from the previous page to the new page by the Context.Item collection. Server.Transfer can be used only for .aspx pages and is specific to ASP and ASP.NET and this method cannot redirect the user to an external page.

Usage Scenario:
  1. You should use Response.Redirect when you want to redirect between pages which reside on different server and domain. Server.Transfer can be used when you want to redirect to a page which resides on the same server.
  2. If you want to perform a quick redirect then go for Server.Transfer (however it can be a little misleading to the user since the Url doesn't physically change). For example Server.Transfer is advisable for wizard style input forms split over multiple pages where the physical change of Url is not of much significance as you move from one form to another form. Server.Transfer conserves server resources. Instead of telling the browser to redirect, it simply changes the focus on the Web server and transfers the request. This means you don't get quite as many HTTP requests coming through, which therefore eases the pressure on your Web server and makes your applications run faster. On the other side Response.Redirect involves an extra round-trip between the client and the server. This extra round-trip can be expensive when there is substantial latency between the client and the server.
  3. Authentication and Force Re-authorization: In Server.Transfer, the Transfer() is actually Server.Execute() + Response.End() and for Execute() what it is to run is the handler of the given path. Here the issue is: ASP.NET does not verify that the current user is authorized to view the resource delivered by the Execute method. Although the ASP.NET authorization and authentication logic runs before the original resource handler is called, ASP.NET directly calls the handler indicated by the Execute method and does not rerun authentication and authorization logic for the new resource. If your application's security policy requires clients to have appropriate authorization to access the resource, the application should force re-authorization or provide a custom access-control mechanism. In Response.Redirect, You can force re-authorization by using the Redirect method instead of the Execute method. Redirect performs a client-side redirect in which the browser requests the new resource. Since this redirect is a new request entering the system, it is subjected to all the authentication and authorization logic of both Internet Information Services (IIS) and ASP.NET security policy. So Response.Redirect is more advisable from a security perspective.
These are some of the main differences between Response.Redirect and Server.Transfer. This article may not be complete and if you find any additional differences or usage scenarios specific to each of those methods, then please feel free to add in the comments section.

Sunday, July 6, 2014

Client Side Validation & Confirmation for Telerik RadAjaxified Controls.

Scenario 1:

In your ASP.NET application using Telerik RadControls, you may need to perform some client side validations in the Client Click events and based on those validations you need to execute the server side code such as OnClick event of a button. 


In the normal scenario you write a code snippet which looks similar to the following code and it works well:

ASPX:
<asp:Button ID="btnSubmit" runat="server" Text="Save" OnClientClick="return validateFields();" OnClick="btnSubmit_Click" />

JavaScript:
<script type="text/javascript">
    function validateFields() {
        if (!somecondition) {
            return false;
        }
    }
</script>


But if the ASP button or Telerik RadButton is ajaxified using Telerik RadAjax you will see that the above code does not work as expected. You cannot find any syntax or logical issues and even if the client side validations are satisfied and the function returns true, still the server side OnClick event wont fire and you will be quiet confused.

Actually this is an exceptional case associated with the RadAjax. Here the issue is that the post-back is cancelled even if the JavaScript function returns true. So in this scenario the JavaScript function returning true though it seems intuitive doesn't behave as expected. when the button is AJAX-enabled by adding the necessary AJAX setting to RadAjaxManager or when the button is placed within a RadAjaxPanel control, you need to alter the Client Click a bit to get it worked as shown in the following code.

ASPX: 
<asp:Button ID="btnSubmit" runat="server" Text="Save" 
OnClientClick="if (!validateFields()) return false;" OnClick="btnSubmit _Click" />

JavaScript:
<script type="text/javascript">
    function validateFields() {
        if (someCondition) {
            return true;
        }
        else {
            return false;
        }
    }
</script>


Scenario 2:

The same issue can happen in a scenario where you may need to provide a confirmation dialog to the user and initiate an AJAX request if accepted.

Confirmation using standard post backs often looks like the following code which also won’t work with a radajaxified button. 

ASPX:
<asp:Button ID="btnDelete" runat="server" OnClientClick="return confirm('Are you sure?');" /> 

So you need to change the code a bit as shown below.

ASPX:
<asp:Button ID="btnDelete" runat="server" OnClientClick="if (!confirm('Are you sure?')) return false;" />

So this is one work around to get over this issue and alternatively you can hook to the OnRequestStart client-side event as shown in the following code in case if you have a more complex logic to implement.

JavaScript:
<telerik:RadCodeBlock ID="RadCodeBlock1" runat="server">
    <script type="text/javascript">
        function OnRequestStart(ajaxControl, eventArgs) {
            var eventTarget = eventArgs.get_eventTarget();
            if (eventTarget == "<%= btnDelete.UniqueID %>") {
            return confirm('Are you sure?');
        }
        else {
            return false;
        }
    }
    </script>
</telerik:RadCodeBlock>


Hope this article will be helpful to developers who are using Telerik RadAjax in their application. Please feel free to provide your healthy and valuable comments to improve the quality of this article.