Monday, April 30, 2007

HTTP 405 -Resource not allowed Error in IIS

       When attempting to POST to a web page in Internet Information Services (IIS) 5.1 under Windows 2000 (Win2k) or Windows XP, you may receive the following error:

The page cannot be displayed The page you are looking for cannot be displayed because the page address is incorrect.

--------------------------------------------------------------------------------

Please try the following: If you typed the page address in the Address bar, check that it is entered correctly. Open the 127.0.0.1 home page and then look for links to the information you want. HTTP 405 - Resource not allowedInternet Information Services

--------------------------------------------------------------------------------

Technical Information (for support personnel) More information:Microsoft Support 

Fig - (1) HTTP 405

Cause

         The file type is not registered in the IIS script map settings (e.g. .html or .htm). IIS 5.1 only allows HTTP requests of type to GET to unmapped files. HTTP requests of type POST, HEAD, and all others are responded to with a 405 resource not allowed error.

          As a security note, you should always remove unused script mappings. This is the default behavior of IIS 6, which will only serve named extensions and refuse all others.

Solution

           Add a script map for the extension. A script map associates a particular file type with a given script module. The web server runs the module on the given file and sends the output to the browser, instead of sending the file directly to the browser.

  1. Go to "Control Panel"-"Administrative Tools"-"Internet Information Services".
  2. Expand the tree to "COMPUTERNAME"-"Web Sites"-"Default Web Site".
  3. Right-click on "Default Web Site" and select "Properties". (Alternately, select "Default Web Site" and press Alt+Enter.)
  4. Select the "Home Directory" tab.
  5. Click the "Configuration" button.
  6. From the "Mappings" tab, select the "Add" button.
  7. Click the "Browse..." button, choose "Dynamic Link Libraries *.dll" from the "Files of Type" dropdown, and select c:\WINDOWS\System32\inetsrv\asp.dll.
  8. Type ".html" (without quotes) in the "Extension" box.
  9. Select the "Limit to:" radio button, and type in "GET, POST" (without quotes) in the box next to it.
  10. Click the "OK" button and close all the dialogs. (If the "OK" button is greyed out, then make sure all the entries are correct and try clicking in the file name box.)

You must adjust the above instructions to your particular OS, web site configuration, and file type. You can associate the file type with a different script engine besides asp.dll, which is the ASP 3.0 script engine. There is no need to give IWAM_COMPUTERNAME permission to the file, only IUSR_COMPUTERNAME needs NTFS read and execute permission.

Happy Programming!!

Friday, April 20, 2007

ASP.NET Session State Management Using SQL Server

            Web applications are by nature stateless. Statelessness is both an advantage and a disadvantage. When resources are not being consumed by maintaining connections and state, scalability is tremendously improved. But the lack of state reduces functionality severely. Ecommerce applications require state to be maintained as the user navigates from page to page. ASP.NET’s Session object makes it easy for developers to maintain state in a Web application. State can be maintained in-process, in a session state server, or in SQL Server.

           In-process state management is the ASP.NET default, and it offers the fastest response time, but does not work in a Web farm. Consequently, it is not practical in high capacity Web applications requiring the load to be spread over multiple servers. A dedicated session state server is shared by all servers in a Web farm, so it provides scalability of the Session objects across all Web servers. It cannot store state persistently. If a dedicated session state server goes down for any reason, all session state data is lost. SQL Server is another alternative for storing session state for all of the servers in a Web farm. Since SQL Server is a database, there is a popular misconception that ASP.NET session state maintained in SQL Server is stored persistently. By default, it is not. If the SQL Server is stopped, the session state data is lost. By making a few simple changes, state can be stored persistently. It is important to understand that persistent is not the same thing as permanent. ASP.NET places a time limit (timeout in web.config) on how long a session’s state is maintained. If the SQL Server is configured to store state persistently and it is down for longer than the ASP.NET session timeout interval, the session state data is lost.

Configuring ASP.NET Session State Management

             Use the sessionState section of the web.config file to configure an ASP.NET Web application to use a SQL Server for session state management. The session state timeout interval is specified by using the timeout parameter.

 

<!--  SESSION STATE SETTINGS
        By default ASP .NET uses cookies to identify which requests
        belong to a particular session.
        If cookies are not available, a session can be tracked by
        adding a session identifier to the URL.
        To disable cookies, set sessionState cookieless="true".
-->
<sessionState
   _ mode="SQLServer"
   _ stateConnectionString="tcpip=127.0.0.1:42424"
   _ sqlConnectionString="data source=127.0.0.1; integrated security=true"
   _ cookieless="false"
   _ timeout="20"
/>

 

               Configure the SQL Server to store Session objects by running a script to create the ASPState database. Version 1.0 of the .NET Framework provides a state database configuration script in %SYSTEMROOT%\Microsoft.NET\Framework\v1.0.3705\InstallSqlState.sql. If you open the file, you will see a statement to create a database called ASPState. This probably adds to the confusion about state being persistent. The ASPState database contains stored procedures that create tables in tempdb. The tables in tempdb are where session state is actually stored. Thus, when the SQL Server is shutdown, all session state is lost. This raises an important question: If the SQL Server is never shutdown, will tempdb eventually become 100 percent full and run out of space? Recall that ASP.NET connections automatically time out and their resources are freed up after the timeout duration is exceeded. The InstallSqlState.sql script creates a job called ASPState_Job_DeleteExpiredSessions to delete expired sessions from tempdb. Recall that ASP.NET does not keep session resources alive indefinitely. To support this feature when a SQL Server is used to maintain state, the SQL Server Agent must be running so that the expired session deletion job runs as needed. By default, the job is scheduled to run every minute. It deletes session state rows with an Expires value less than the current time. The account under which the SQL Server Agent runs must have the privilege to execute the DeleteExpiredSessions stored procedure.

          ASPState database scripts come in pairs. InstallSqlState.sql creates the database and supporting objects. UninstallSqlState.sql drops the database and all supporting objects (e.g., the job to delete expired sessions). You cannot drop a database if it is in use, so if the UninstallSqlState.sql script fails with this error message:


Server: Msg 3702, Level 16, State 4, Line 4
Cannot drop the database 'ASPState' because it is currently in use.


 

Microsoft Knowledge Base article 311209 says to stop the Web server service to overcome this error. An “uninstallation” failure can still occur even if the Web server service is stopped. Additionally, you might not want to stop the Web server service because that will cause all Web applications on the server to stop. Instead, use the SQL Server Enterprise Manager. Find the processes accessing the ASPState database and delete them. If users are still accessing the application and causing new processes to be created faster than you can delete them, go to the IIS console and select the Properties for the Web application. On the Directory tab, click the Remove button. This will prevent access to the Web application and allow you to kill any remaining processes accessing the ASPState database. Once the processes are gone, uninstallation should completely successfully. Be sure to go back to the IIS console and click the Create button to restore the Web application to normal working order if you previously clicked the Remove button.

Version 1.0 of the .NET Framework does not provide a script for creating an ASPState database that maintains state persistently. However, Microsoft Knowledge Base article 311209 does provide a link for downloading InstallPersistentSqlState.sql and UninstallPersistentSqlState.sql. The InstallPersistentSqlState.sql script causes the session state data to be stored in permanent tables in ASPState instead of temporary tables in tempdb.

Version 1.1 of the .NET Framework provides both InstallPersistentSqlState.sql and InstallSqlState.sql. The Framework Version 1.1 scripts are found in the %SYSTEMROOT%\Microsoft.NET\Framework\v1.1.4322 folder. Although the 1.0 and 1.1 versions of InstallPersistentSqlState.sql accomplish the same thing, they are different. For SQL Server 2000 and above, the 1.1 version creates the ASPState stored procedures using GETUTCDATE instead of GETDATE. The 1.0 version always uses GETDATE. You can use the Framework version 1.1 script to create a database for an application using the Framework version 1.0.

If you specify integrated security in the web.config file, you will have to create a server login for the ASPNET user and then make the login a user in the ASPState database. You will also have to grant permissions to the ASPNET user to use database objects. If you do not store state persistently, the ASPNET user must be granted permissions to use state management objects in tempdb. The prudent approach is to grant no more permissions than are absolutely necessary. Here are the permissions I granted after executing the Version 1.0 InstallSqlState.sql script:


USE masterGOEXECUTE sp_grantlogin [DBAZINE\ASPNET]GO USE ASPState GO EXECUTE sp_grantdbaccess [DBAZINE\ASPNET] GRANT EXECUTE on TempGetAppId to [DBAZINE\ASPNET] GRANT EXECUTE on TempGetStateItemExclusive to [DBAZINE\ASPNET] GRANT EXECUTE on TempInsertStateItemShort to [DBAZINE\ASPNET] GO USE tempdb -- remove this if using persistent state GO -- remove this if using persistent state EXECUTE sp_grantdbaccess [DBAZINE\ASPNET] -- remove this if persistent state GRANT SELECT on ASPStateTempApplications to [DBAZINE\ASPNET] GRANT INSERT on ASPStateTempApplications to [DBAZINE\ASPNET] GRANT SELECT on ASPStateTempSessions to [DBAZINE\ASPNET] GRANT INSERT on ASPStateTempSessions to [DBAZINE\ASPNET] GRANT UPDATE on ASPStateTempSessions to [DBAZINE\ASPNET] GO


 

If you use the InstallPersistentSqlState.sql, remove the three lines as indicated above.

Consider the grants shown above as a starting point for creating your own script appropriate for your environment.

Conclusion


ASP.NET offers two simple solutions to session state management in a Web farm. Only SQL Server offers persistent state management. A dedicated session state server does not offer persistent state management, but does not require the creation of a database (one more thing for the DBA to administer). The value of persistent state has to be weighed carefully. Maintaining session state persistently is useful only if the SQL Server can be brought back up within the session state timeout specified in the web.config. For those situations where using a SQL Server as a state server makes sense, ASP.NET makes it easy.

Referenced from this article.

Happy Programming!!!

Thursday, April 19, 2007

Unable to load DLL 'ABCpdfCE6.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)

    This is a common error that may occure while you are using ABCPDF to generate PDF in asp.net. If you install the component on your machine and use that in application it works fine. However when you copy that application on a machine on which component is not installed, it throws eception as "Unable to load DLL 'ABCpdfCE6.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)".

     Solution to this issue is mentioned below.

1. Check that you have properly added the reference of "ABCpdf.DLL" in your application.

2. Copy "ABCpdfCE6.dll" in your bin folder. You can found this dll at "C:\Program Files\WebSupergoo\ABCpdf6 .NET\Common\" on machine where you had install the component.

 

Happy Programming !!

Create PDF in ASP.NET

           In my current web application I have to genarate PDF for subcription information and need to attach in email. I was searching a component which can generate PDF from HTML content. ABC PDF is really a cool component to generate PDF and really simple to use in application. You can find the trial version here.

Happy Programming !!

Wednesday, April 18, 2007

Session Management in ASP.NET

ASP.NET Session State: Architectural and Performance Considerations

I recently came across a great post on one of the internal forums describing the strengths and weaknesses of different ASP.NET session state strategies.

As you're probably aware, state management is an important consideration for web developers. The HTTP protocol is connectionless, so any web application that persists data across multiple web page requests needs some mechanism to ensure this session-based data is maintained. Examples of session-based data include shopping carts (on an ecommerce site), the currently logged-on user credentials, and other application-specific data that would normally be held on a client. Various strategies have been utilised over the last few years, including hidden forms, cookies and server-based state engines. Of these choices, the latter is perhaps architecturally most attractive since it reduces the dependence on a client; unfortunately, maintaining session state on the server can be expensive on resources and makes it hard to scale out using web farms or secure pages with HTTPS.

Enter the ASP.NET session state engine, which attempts to make server-side session state a much more viable option. ASP.NET offers three separate choices for session state storage when it's switched on: locally on the server (InProc), remotely in a SQL Server database (SqlServer), or remotely using a session state service (StateServer). I'll go through each of those options and compare the benefits of each.

InProc

The local option is not dissimilar to that provided by ASP, in that it requires all requests to come to the same physical server rather than being randomly split across multiple IIS machines. The upside is that it's very fast (it runs in-process), and it's simple to implement. If you've just got one web server, this is the best choice in most scenarios. The only time when you might want to consider something else in this scenario is when the session data is expensive to rebuild, since any InProc session data is flushed when the ASP.NET worker process or IIS restarts. If, for example, you're maintaining a shopping cart as local session data that gets cleared out, you risk annoying customers sufficiently that they take their business elsewhere.

For multiple servers, InProc is unsuitable unless you can implement some form of server affinity, so that every time a particular client requests a web page they are directed back to that same server. Services such as Network Load Balancing (part of Windows Server 2003 Enterprise Edition) can provide this, although they inevitably add their own overhead.

StateServer

I've come across a few developers who haven't come across this choice. The state server relies on a Windows service which is disabled by default, which perhaps explains why people haven't noticed it - go to Administrative Tools / Services and enable the ASP.NET State Service to get it working. You can run the state service on a dedicated machine or shared with a web server host; the main requirement to make this service work efficiently is plenty of RAM. Because the service is isolated from IIS, you can restart IIS without losing the session data contained within it, and you can point multiple distributed ASP.NET boxes at the same service, thereby removing server affinity issues. However, the session data isn't persisted onto disk, so it can't be backed up and a server reboot will lose the data. On the plus side, you don't need SQL Server or anything beyond a Windows licence to run it, making this option easy to set up and maintain. This option is however signficantly slower than using InProc, due to network latency and roundtrip costs. Keeping the state server on a dedicated private LAN with the other web server boxes will help.

Finally, don't forget that you can run the ASP.NET State Service in a single web server environment - this provides durability against IIS restarts, but at a performance cost due to it running out of process.

SqlServer

This is the high-end option in terms of flexibility and reliability, but is also the most expensive to build and maintain. Rather than storing session data in memory, it is persisted to a SQL Server instance. It's more reliable than any of the other approaches, since the data is persisted in a more durable form (e.g. it will survive a server restart and can be backed up). You can even use SQL Server clustering support to increase session state reliability still further. From a performance point of view, it's generally comparable to the StateServer service when you've got multiple web servers using it for session state. The session state itself is stored as a BLOB in a persisted or temporary table, which can reduce the serialization cost but makes it harder to view the session data itself.

In most cases, integrated Windows authentication is the best choice, preferably utilising Kerberos (NTLM requires an extra roundtrip for authentication). Connection pooling can be used to minimise the initial performance hit.

Happy Programming !!

Session Management in ASP.NET

ASP.NET Session State: Architectural and Performance Considerations

I recently came across a great post on one of the internal forums describing the strengths and weaknesses of different ASP.NET session state strategies. Its author, J.D. Meier, has graciously given me permission to use it as the basis of a blog entry.

As you're probably aware, state management is an important consideration for web developers. The HTTP protocol is connectionless, so any web application that persists data across multiple web page requests needs some mechanism to ensure this session-based data is maintained. Examples of session-based data include shopping carts (on an ecommerce site), the currently logged-on user credentials, and other application-specific data that would normally be held on a client. Various strategies have been utilised over the last few years, including hidden forms, cookies and server-based state engines. Of these choices, the latter is perhaps architecturally most attractive since it reduces the dependence on a client; unfortunately, maintaining session state on the server can be expensive on resources and makes it hard to scale out using web farms or secure pages with HTTPS.

Enter the ASP.NET session state engine, which attempts to make server-side session state a much more viable option. ASP.NET offers three separate choices for session state storage when it's switched on: locally on the server (InProc), remotely in a SQL Server database (SqlServer), or remotely using a session state service (StateServer). I'll go through each of those options and compare the benefits of each.

InProc

The local option is not dissimilar to that provided by ASP, in that it requires all requests to come to the same physical server rather than being randomly split across multiple IIS machines. The upside is that it's very fast (it runs in-process), and it's simple to implement. If you've just got one web server, this is the best choice in most scenarios. The only time when you might want to consider something else in this scenario is when the session data is expensive to rebuild, since any InProc session data is flushed when the ASP.NET worker process or IIS restarts. If, for example, you're maintaining a shopping cart as local session data that gets cleared out, you risk annoying customers sufficiently that they take their business elsewhere.

For multiple servers, InProc is unsuitable unless you can implement some form of server affinity, so that every time a particular client requests a web page they are directed back to that same server. Services such as Network Load Balancing (part of Windows Server 2003 Enterprise Edition) can provide this, although they inevitably add their own overhead.

StateServer

I've come across a few developers who haven't come across this choice. The state server relies on a Windows service which is disabled by default, which perhaps explains why people haven't noticed it - go to Administrative Tools / Services and enable the ASP.NET State Service to get it working. You can run the state service on a dedicated machine or shared with a web server host; the main requirement to make this service work efficiently is plenty of RAM. Because the service is isolated from IIS, you can restart IIS without losing the session data contained within it, and you can point multiple distributed ASP.NET boxes at the same service, thereby removing server affinity issues. However, the session data isn't persisted onto disk, so it can't be backed up and a server reboot will lose the data. On the plus side, you don't need SQL Server or anything beyond a Windows licence to run it, making this option easy to set up and maintain. This option is however signficantly slower than using InProc, due to network latency and roundtrip costs. Keeping the state server on a dedicated private LAN with the other web server boxes will help.

Finally, don't forget that you can run the ASP.NET State Service in a single web server environment - this provides durability against IIS restarts, but at a performance cost due to it running out of process.

SqlServer

This is the high-end option in terms of flexibility and reliability, but is also the most expensive to build and maintain. Rather than storing session data in memory, it is persisted to a SQL Server instance. It's more reliable than any of the other approaches, since the data is persisted in a more durable form (e.g. it will survive a server restart and can be backed up). You can even use SQL Server clustering support to increase session state reliability still further. From a performance point of view, it's generally comparable to the StateServer service when you've got multiple web servers using it for session state. The session state itself is stored as a BLOB in a persisted or temporary table, which can reduce the serialization cost but makes it harder to view the session data itself.

In most cases, integrated Windows authentication is the best choice, preferably utilising Kerberos (NTLM requires an extra roundtrip for authentication). Connection pooling can be used to minimise the initial performance hit.

Happy Programming !!

Difference between user defined function and stored procedure

Advantages of User Defined Functions

Before SQL 2000, User Defined Functions (UDFs), were not available. Stored Procedures were often used in their place. When advantages or disadvantages of User Defined Functions are discussed, the comparison is usually to Stored Procedures.

One of the advantages of User Defined Functions over Stored Procedures, is the fact that a UDF can be used in a Select, Where, or Case statement. They also can be used to create joins. In addition, User Defined Functions are simpler to invoke than Stored Procedures from inside another SQL statement.

Disadvantages of User Defined Functions

User Defined Functions cannot be used to modify base table information. The DML statements INSERT, UPDATE, and DELETE cannot be used on base tables. Another disadvantage is that SQL functions that return non-deterministic values are not allowed to be called from inside User Defined Functions. GETDATE is an example of a non-deterministic function. Every time the function is called, a different value is returned. Therefore, GETDATE cannot be called from inside a UDF you create.

Types of User Defined Functions

There are three different types of User Defined Functions. Each type refers to the data being returned by the function. Scalar functions return a single value. In Line Table functions return a single table variable that was created by a select statement. The final UDF is a Multi-statement Table Function. This function returns a table variable whose structure was created by hand, similar to a Create Table statement. It is useful when complex data manipulation inside the function is required.

Scalar UDFs

Our first User Defined Function will accept a date time, and return only the date portion. Scalar functions return a value. From inside Query Analyzer, enter:

 

CREATE FUNCTION dbo.DateOnly(@InDateTime datetime)
RETURNS varchar(10)
AS
BEGIN
        DECLARE @MyOutput varchar(10)
        SET @MyOutput = CONVERT(varchar(10),@InDateTime,101)
        RETURN @MyOutput
END

To call our function, execute: SELECT dbo.DateOnly(GETDATE())

Notice the User Defined Function must be prefaced with the owner name, DBO in this case. In addition, GETDATE can be used as the input parameter, but could not be used inside the function itself. Other built in SQL functions that cannot be used inside a User Defined Function include: RAND, NEWID, @@CONNCECTIONS, @@TIMETICKS, and @@PACK_SENT. Any built in function that is non-deterministic.

The statement begins by supplying a function name and input parameter list. In this case, a date time value will be passed in. The next line defines the type of data the UDF will return. Between the BEGIN and END block is the statement code. Declaring the output variable was for clarity only. This function should be shortened to:

 

CREATE FUNCTION testDateOnly(@InDateTime datetime)
RETURNS varchar(10)
AS
BEGIN
        RETURN CONVERT(varchar(10),@InDateTime,101)   
END

Inline Table UDFs

These User Defined Functions return a table variable that was created by a single select statement. Almost like a simply constructed non-updatable view, but having the benefit of accepting input parameters.

This next function looks all the employees in the pubs database that start with a letter that is passed in as a parameter. In Query Analyzer, enter and run:

 

USE pubs
GO
 
CREATE FUNCTION dbo.LookByFName(@FirstLetter char(1))
RETURNS TABLE
AS
RETURN SELECT *
FROM employee
WHERE LEFT(fname, 1) =  @FirstLetter

To use the new function, enter:

SELECT * FROM dbo.LookByFName('A')

All the rows having a first name starting with A were returned. The return is a Table Variable, not to be confused with a temporary table. Table variables are new in SQL 2000. They are a special data type whose scope is limited to the process that declared it. Table variables are stated to have performance benefits over temporary tables. None of my personal testing has found this result though.

Multi Statement UDFs

Multi Statement User Defined Functions are very similar to Stored Procedures. They both allow complex logic to take place inside the function. There are a number of restrictions unique to functions though. The Multi Statement UDF will always return a table variable--and only one table variable. There is no way to return multiple result sets. In addition, a User Defined Function cannot call a Stored Procedure from inside itself. They also cannot execute dynamic SQL. Remember also, that UDFs cannot use non-deterministic built in functions. So GETDATE and RAND cannot be used. Error handling is restricted. RAISERROR and @@ERROR are invalid from inside User Defined Functions. Like other programming languages, the purpose of a User Defined Function is to create a stand-alone code module to be reused over and over by the global application.

For a Multi Statement test, we will create a modified version of the LookByFName function. This new function will accept the same input parameter. But rather than return a table from a simple select, a specific table will be created, and data in it will be manipulated prior to the return:

CREATE FUNCTION dbo.multi_test(@FirstLetter char(1))
RETURNS @Result TABLE
        (
        fname varchar(20),
        hire_date datetime,
        on_probation char(1)
        )
AS
BEGIN
        INSERT INTO @Result
               (fname, hire_date)
               SELECT fname, hire_date
               FROM employee
               WHERE LEFT(fname, 1) =  @FirstLetter
        
        UPDATE @Result
        SET on_probation = 'N'
        
        UPDATE @Result
        SET on_probation = 'Y'
        WHERE hire_date < '01/01/1991'
        
        RETURN
END

To use the new function, execute:

SELECT * FROM dbo.multi_test('A')

With the new Multi Statement Function, we can manipulate data like a Stored Procedure, but use it in statement areas like a View.

For example, only specific columns can be returned.

SELECT fname FROM dbo.multi_test('A')

The function can also be joined like a view:

SELECT e.lname, f.fname
FROM employee e INNER JOIN dbo.multi_test('A') f ON e.fname = f.fname
 

Conclusion

User Defined Functions offer an excellent way to work with code snippets. The main requirement is that the function be self-contained. Not being able to use non-deterministic built in functions is a problem, but if it can be worked around, UDFs will provide you with a programming plus.

 

Happy Programming !!

 

Tuesday, April 17, 2007

Javascript function to check valid decimal value with specified digits after decimal point

    Below is the function that validates only positive decimal numbers in text box. You can specify number of digits that can be allow after decimal point.

 

var DigitsAfterDecimal = 8;
function
CheckUnit()
{

if(document.getElementById
("TextBoxName").value == '' )
{
alert("Please enter valid decimal
value");

return false;
}
else
{

if(isNaN(document.getElementById
("TextBoxName").value))
{
alert("Please enter valid decimal
value")
;


return false;
}
else
{
var val = document.getElementById
("TextBoxName").value;
if(val.indexOf(".") > -1)
{

if(val.length - (val.indexOf
(".")+1) >
DigitsAfterDecimal)
{
alert("Please enter valid
decimal value. Only " +
DigitsAfterDecimal + "
digits are allowed after
decimal.")
;



return false;
}
else
{
return true;
}
}
else
{
if(parseInt(val) > 0)
{
return true;
}
else
{
alert("Value must be
greater than 0"
);

return false;
}
}
}
}
}
Happy Programming !!

Sunday, April 08, 2007

Transferring sessions from asp to aspx

          In my starting days with dotnet before 2 years, all vendors were converting from ASP to ASP.NET. They still wanted some of the pages in ASP. The real problem is to transfer session from asp page to aspx page.  The easiest way I found was shown below.

         Lest say that you have a page Old.asp and a page New.aspx . You need to transfer the session from Old to New. The idea is create an intermediate forms(pages)  that can help you in transferring the sessions.  First Create Step1.asp page and redirect to this page from "Old.asp" page . This page will creates a form with hidden fields which stores the value of all session variables as shown below,

<html>
<
head>
<
meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<
title>Step 1</title>
</
head>
<
body>
<%
Response.Write("<form name=t id=t action=Step2.aspx method=post >")
For each Item in Session.Contents
Response.Write("<input type=hidden name=" & Item)
Response.Write( " value=" & Session.Contents(item) & " >")
next
Response.Write("</FORM>")
Response.Write("<script>t.submit();</script>")
%>
</
body>
</
html>

Fig - (1) First Step to transfer the session from asp to aspx.


       The page shown in Fig - (1) creates the form will create new form which has action attribute set to "Step2.aspx" page. This page will loop through all the session variables and generates hidden field for each. After that, java script submit the page to aspx page. Now look at the "Step2.aspx" page.

public class WebForm1 : System.Web.UI.Page
{
private void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the page here
for(int i=0;i<Request.Form.Count;i++)
{
Session[Request.Form.GetKey(i)]=Request.Form[i].ToString();
}
// Destination aspx page to which you need to transfer sessions
Server.Transfer(Session["DestPage"].ToString(),true);

}
}

Fig - (2)  Step2 to transfer session from asp to aspx.


        This page will loop through all the fields of posted form using "Request.Form" and add the values in session. The last line transfer this aspx page to destination aspx page which is "New.aspx".


Happy Programming !

Friday, April 06, 2007

Validation of viewstate MAC failed.

            I was trying to post my aspx page to new page using JavaScript. The common methods "document.form1.submit()". I have specified action and method attribute also. Still I was getting error on form submit as shown below,

"Validation of viewstate MAC failed. If this application is hosted by a Web Farm or cluster, ensure that <machineKey> configuration specifies the same validationKey and validation algorithm. AutoGenerate cannot be used in a cluster."

         Below is the code I was using for form submission.

document.form1.action="New.aspx"
document.form1.submit();

Fig - (1) Javascript to submit the form.

      I had written above script on submit button. After searching I found the reason for that. In ASP.NET, there is a specific method "__dopostback()" which allows user to submit the form to server(postback). Each time form is submitted with "post" method, CLR checks for valid viewstate so that there can not be any type of injection.

        To solve this problem you have set "name" attribute of viewstate before submitting. The code is shown below.

ocument.form1.action="New.aspx";
document.form1.__VIEWSTATE.name="name";
document.form1.submit();

Fig - (2) Javascript to submit the form without error.

Happy Programming !

Tuesday, April 03, 2007

Single Sign on between Form Authentication Applications

    In my recent interview, I faced an interesting question. "Can we use single sign on for diffrent Form Authentication Sites?". Obviously my answer was "No Idea". After that I search on net for this and found that, yes !! we can do that. Below is the way to achieve this.

 

SSO for parent and child application in the virtual sub-directory
Lets assume that we have two .NET applications - Foo and Bar, and Bar is running in a virtual sub-directory of Foo (http://foo.com/bar). Both applications implement Forms authentication. Implementation of Forms authentication requires you to override the Application_AuthenticateRequest, where you perform the authentication and upon successful authentication, call FormsAuthentication.RedirectFromLoginPage, passing in the logged-in user name (or any other piece of information that identifies the user in the system) as a parameter. In ASP.NET the logged-in user status is persisted by storing the cookie on the client computer. When you call RedirectFromLoginPage, a cookie is created which contains an encrypted FormsAuthenticationTicket with the name of the logged-in user . There is a section in web.config that defines how the cookie is created:

<authentication mode="Forms">
   <forms name=".FooAuth" protection="All" timeout="60" loginUrl="login.aspx" />
</authentication>

 <authentication mode="Forms">
   <forms name=".BarAuth" protection="All" timeout="60" loginUrl="login.aspx" />
</authentication>

The important attributes here are name and protection. If you make them match for both Foo and Bar applications, they will both write and read the same cookie using the same protection level, effectively providing SSO:

<authentication mode="Forms">
   <forms name=".SSOAuth" protection="All" timeout="60" loginUrl="login.aspx" />
</authentication>

When protection attribute is set to "All", both encryption and validation (via hash) is applied to the cookie. The default validation and encryption keys are stored in the machine.config file and can be overridden in the application’s web.config file. The default value is this:

<machineKey validationKey="AutoGenerate,IsolateApps" decryptionKey=" AutoGenerate,IsolateApps" validation="SHA1" />

IsolateApps means that a different key will be generated for every application. We can’t have that. In order for the cookie to be encrypted and decrypted with the same key in all applications either remove the IsolateApps option or better yet, add the same concrete key to the web.config of all applications using SSO:

<machineKey validationKey="F9D1A2D3E1D3E2F7B3D9F90FF3965ABDAC304902" decryptionKey="F9D1A2D3E1D3E2F7B3D9F90FF3965ABDAC304902F8D923AC" validation="SHA1" />

      I found one good artile on this here

Happy Programming !!