Saturday, March 17, 2012

Localizing an ASP.NET Application



Globalization is the process of designing and developing applications that function for multiple cultures, and localization is the process of customizing your application for a given culture and locale. The topics in this section describe how to create ASP.NET Web applications that can be adapted to different languages and cultures.

Example for Localization:-

Imports System.Threading.Thread
Imports System.Threading
Public Class Globalization
    Public Sub New()
        ' Creating a Global Culture specific to our application.
        Dim cultureInfo As New System.Globalization.CultureInfo("en-US")
        ' Creating the DateTime Information specific to our application.
        Dim dateTimeInfo As New System.Globalization.DateTimeFormatInfo()
        ' Defining various date and time formats.
        dateTimeInfo.DateSeparator = "/"
        dateTimeInfo.LongDatePattern = "MM/dd/yyyy"
        dateTimeInfo.ShortDatePattern = "MM/dd/yyyy"
        ' Setting application wide date time format.
        cultureInfo.DateTimeFormat = dateTimeInfo
        ' Assigning our custom Culture to the application current thread.
        'Application.CurrentCulture = cultureInfo;
        Thread.CurrentThread.CurrentCulture = cultureInfo
        Thread.CurrentThread.CurrentUICulture = cultureInfo
    End Sub
End Class

Create an instance for the above class in the base form of your project.  
Now the datetime will be treated in the format of  MM/dd/yyyy 

Some Expression Web 4 Add-Ins


Highlighting the current date in AJAX CALENDER CONTROL



Add the following script to your aspx page

function CurrentDateShowing(e) 
    {        
        if (!e.get_selectedDate() || !e.get_element().value)
        e._selectedDate = (new Date()).getDateOnly(); 
    }   

and set the property OnClientShowing="CurrentDateShowing".

Example:


                 

Custom Error Pages In ASP.NET



* Errors And Exceptions In ASP.NET - covers different kinds of errors, try-catch blocks, introduces Exception object, throwing an exception and page_error procedure.
* Application Level Error Handling in ASP.NET - goes a level higher and explains handling of unhandled errors by using Application_Error procedure in Global.asax file, using of custom Http modules, sending notification e-mail to administrator, show different error pages based on roles and logging errors to text files, database or EventLog.

This tutorial deals with user experience when error occurs. When error is occurred on ASP.NET web application, user will get default error page (which is not so nice looking, also known as "Yellow screen of death"). This error page confuses average visitor who don't know the meaning of "Runtime Error". Although developers like to know many details about an error, it is better to show more friendly error page to your users.

          Web.config file contains a customErrors section inside . By default, this section looks like this: <customErrorsmode="RemoteOnly" />
As you see, there is mode parameter inside customErrors tag which value is "RemoteOnly". This means that detailed messages will be shown only if site is accessed through a http://localhost. Site visitors, who access from external computers will see other, more general message, like in image bellow:



mode parameter can have three possible values:
RemoteOnly - this is default value, detailed messages are shown if you access through a localhost, and more general (default) error message to remote visitors.
On - default error message is shown to everyone. This could be a security problem since part of source code where error occurred is shown too.
Off - detailed error message is shown to everyone.
Default ASP.NET error message hides details about error, but still is not user friendly. Instead of this page, ASP.NET allows you to create your own error page. After custom error page is created, you need to add a reference to it in customErrors section by using a defaultRedirect parameter, like in code snippet bellow:

<customErrors mode="RemoteOnlydefaultRedirect="~/DefaultErrorPage.htm" />

When error occured, ASP.NET runtime will redirect visitor to DefaultErrorPage.htm. On custom error page you can gently inform your visitors what happened and what they can do about it.

DefaultErrorPage.htm will display when any error occurs. Also, there is a possibility to show different custom error pages for different types of exceptions. We can do that by using sub tag. In code sample bellow, specialized pages are shown for errors 404 (File Not Found) and error 403 (Forbidden). 

<customErrors mode="OndefaultRedirect="~/DefaultErrorPage.htm" >
  <error statusCode="404" redirect="~/FileNotFound.htm"/>
  <error statusCode="403" redirect="~/Forbidden.htm"/>
customErrors>

How to set error page for every ASP.NET page

Custom pages configured in Web.config affect complete web site. It is possible also to set error page for every single ASP.NET page. We can do this by using @Page directive. Code could look like this:

<%@ Page language="C#" Codebehind="SomePage.aspx.cs" errorPage="MyCustomErrorPage.htm" AutoEventWireup="false"%>

Http Error page codes

There are different Http codes that your web application could return. Some errors are more often than others. You probably don't need to cover all cases. It is ok to place custom error pages for the most common error codes and place default error page for the rest.

400 Bad Request

Request is not recognized by server because of errors in syntax. Request should be changed with corrected syntax.

401 Not Authorized

This error happens when request doesn't contain authentication or authorization is refused because of bad credentials.

402 Payment Required

Not in use, it is just reserved for the future

403 Forbidden

Server refused to execute request, although it is in correct format. Server may or may not provide information why request is refused.

404 Not Found

Server can not find resource requested in URI. This is very common error, you should add custom error page for this code.

405 Method Not Allowed

There are different Http request methods, like POST, GET, HEAD, PUT, DELETE etc. that could be used by client. Web server can be configured to allow or disallow specific method. For example, if web site has static pages POST method could be disabled. There are many theoretical options but in reality this error usually occurs if POST method is not allowed.

406 Not Acceptable

Web client (browser or robot) could try to receive some data from web server. If that data are not acceptable web server will return this error. Error will not happen (or very rarely) when web browser request the page.

407 Proxy Authentication Required

This error could occur if web client accesses to web server through a proxy. If proxy authentication is required you must first login to proxy server and then navigate to wanted page. Because of that this error is similar to error 401 Not Authorized, except that here is problem with proxy authentication.

408 Request Timeout

If connection from web client and server is not established in some time period, which is defined on web server, then web server will drop connection and send error 408 Request Timeout. The reason could be usually temporarily problem with Internet connection or even to short time interval on web server.

409 Conflict

This error rarely occurs on web server. It means that web request from client is in conflict with some server or application rule on web server.

410 Gone

This error means that web server can't find requested URL. But, as opposed to error 404 Not Found which says: "That page is not existing", 410 says something like: "The page was here but not anymore". Depending of configuration of web server, after some time period server will change error message to 404 Not Found.

411 Length Required

This error is rare when web client is browser. Web server expects Content-Length parameter included in web request.

412 Precondition Failed

This is also rare error, especially if client is web browser. Error occurs if Precondition parameter is not valid for web server.

413 Request Entity Too Large

This error occurs when web request is to large. This is also very rare error, especially when request is sent by web browser.

414 Request URI Too Long

Similar like error 413, error occurs if URL in the web request is too long. This limit is usually 2048 to 4096 characters. If requested URL is longer than server's limit then this error is returned. 2048 characters is pretty much, so this error occurs rarely. If your web application produces this error, then it is possible that is something wrong with your URLs, especially if you build it dynamically with ASP.NET server side code.

415 Unsupported Media Type

This error occurs rarely, especially if request is sent by web browser. It could be three different reasons for this error. It is possible that requested media type doesn't match media type specified in request, or because of incapability to handle current data for the resource, or it is not compatible with requested Http method.

416 Requested Range Not Satisfied

This is very rare error. Client request can contain Range parameter. This parameter represents expected size of resource requested. For example, if client asks for an image, and range is between 0 and 2000, then image should not be larger from 2000 bytes. If image is larger, this error is returned. However, web page hyperlinks usually don't specify any Range value so this error rarely occurs.

417 Expectation Failed

This is also rare error, especially if client is web browser. There is Expect parameter of request, if this Expect is not satisfied Expectation error is returned.

500 Internal Server Error

This is very common error; client doesn't know what the problem is. Server only tells that there is some problem on server side. But, on the server side are usually more information provided. If server hosts ASP.NET application, then this often means that there is an error in ASP.NET application. More details about error could be logged to EventLog, database or plain text files. To see how to get error details take a look at Application Level Error Handling In ASP.NET tutorial.

501 Not Implemented

This is rare error. It means that web server doesn't support Http method used in request. Common Http methods are POST, GET, HEAD, TRACE etc. If some other method is used and web server can't recognize it, this error will be returned.

502 Bad Gateway

This error occurs when server is working as gateway and need to proceed request to upstream web server. If upstream web server response is not correct, then first server will return this error. The reason for this error is often bad Internet connection some problem with firewall, or problem in communication between servers.

503 Service unavailable

This error means that server is temporally down, but that is planned, usually because a maintenance. Of course, it is not completely down because it can send 503 error :), but it is not working properly. Client should expect that system administrator is working on the server and server should be up again after problem is solved.

504 Gateway Timeout

Similar to error 502 Bad Gateway, there is problem somewhere between server and upstream web server. In this case, upstream web server takes too long to respond and first server returned this error. This could happen for example if your Internet connection is slow, or it is slow or overloaded communication in your local network.

505 HTTP Version Not Supported

Web server doesn't support Http version used by web client. This should be very rare error. It could happen eventually if web client tries to access to some very old web server, which doesn't support newer Http protocol version (before v. 1.x).

Show different error pages based on roles

By using of RemoteOnly value for customErrors mode parameter in Web.config you can get detailed messages when you access through a localhost and custom messages if you access remotely. This could be a problem, because sometime you need to access remotely to web application and still see detailed messages. If you have shared hosting than this is only option. Of course, you still don't want to show error details to end users.
If you use some role based security architecture you can show detailed message to single logged user (you) or to all users that belong to some role, for example "Developers". On this way, developers logged in to web application will see detailed error messages and your users will still see just friendly custom notification.
To implement this idea we need to add some code to Application_Error procedure in Global.asax file. Code could look like this:
[ C# ]
void Application_Error(object sender, EventArgs e)
{
if(Context != null)
{
// Of course, you don't need to use both conditions bellow
// If you want, you can use only your user name or only role name
if(Context.User.IsInRole("Developers") ||
(Context.User.Identity.Name == "YourUserName") )
{
// Use Server.GetLastError to recieve current exception object
Exception CurrentException = Server.GetLastError();

// We need this line to avoid real error page
Server.ClearError();

// Clear current output
Response.Clear();

// Show error message as a title
Response.Write("

Error message: " + CurrentException.Message + "

");
// Show error details
Response.Write("Error details:
"
);
Response.Write(CurrentException.ToString());
}
}
}
[ VB.NET ]
Sub Application_Error(ByVal sender As ObjectByVal e As EventArgs)
If Context IsNot Nothing Then
' Of course, you don't need to use both conditions bellow
' If you want, you can use only your user name or only role name
If Context.User.IsInRole("Developers"Or _
(Context.User.Identity.Name = "YourUserName"Then

' Use Server.GetLastError to recieve current exception object
Dim CurrentException As Exception = Server.GetLastError()

' We need this line to avoid real error page
Server.ClearError()

' Clear current output
Response.Clear()

' Show error message as a title
Response.Write("

Error message: " & _
CurrentException.Message & "

")
' Show error details
Response.Write("Error details:
"
)
Response.Write(CurrentException.ToString())
End If
End If
End Sub

ASP.NET Custom Error Pages Remarks

By using custom error pages you can achieve more professional look for your ASP.NET web application. Although your visitors will not be happy if something is not working, it will be much better if you told them that something is wrong, but you are aware of that and you will correct it as soon as possible. That will connect you closer to your users. Errors are almost unavoidable, but your competence to deal with them makes difference.
I hope that you find this tutorial helpful. Happy programming!

Add JavaScript programmatically using RegisterStartupScript during an Asynchronous postback


          The ClientScriptManager class contains various methods to add client scripts to a webpage using server side code. For example: you may need to add javascript programmatically to the page on a button click before posting back the page. One of the methods you can use is the  RegisterStartupScript() method of the ClientScriptManager class. However, this method does not work if the button control is wrapped inside an UpdatePanel. In this short article, we will explore how to add javascript programmatically using the ScriptManager.RegisterStartupScript, while performing an asynchronous postback. I also aim to cover some common mistakes developers make while using the ScriptManager class to add client scripts programmatically.

We will study two scenarios in this article: 

The first one, where we will use the ClientScript.RegisterStartupScript() to add script dynamically on a button click. We will add a label displaying the time, as well as change the color of the label to make sure the postback occurred.

In the second scenario, we will add the button and label control inside an UpdatePanel. We will try and use the same code, which will not work. We will then see how to add javascript programmatically during an async postback.

Scenario 1:
Create an ASP.NET project. Now add a Label(lblDisplayDate) and a Button(btnPostback) control to the page.
On the Button click, register the following script dynamically using the ClientScriptManager.RegisterStartupScript to change the color of the label controls to Red.
C#
protected void Page_Load(object sender, EventArgs e)
{
    lblDisplayDate.Text = System.DateTime.Now.ToString("T");
}

protected void btnPostback_Click(object sender, EventArgs e)
{
    System.Text.StringBuilder sb = new System.Text.StringBuilder();
    sb.Append(@"");

    if (!ClientScript.IsStartupScriptRegistered("JSScript"))
    {
        ClientScript.RegisterStartupScript(this.GetType(), "JSScript", sb.ToString());
    }
}
VB.NET
Protected Sub Page_Load(ByVal sender As ObjectByVal e As EventArgs)
      lblDisplayDate.Text = System.DateTime.Now.ToString("T")
End Sub

Protected Sub btnPostback_Click(ByVal sender As ObjectByVal e As EventArgs)
      Dim sb As System.Text.StringBuilder = New System.Text.StringBuilder()
      sb.Append("")

      If (Not ClientScript.IsStartupScriptRegistered("JSScript")) Then
            ClientScript.RegisterStartupScript(Me.GetType(), "JSScript", sb.ToString())
      End If
End Sub
When you run the application and click on the button, you will observe that the label is updated with a new time and the color of the label turns to red. This confirms that there was a postback, as well as the dynamically added JavaScript executed.

Scenario 2:
Now wrap the label and the button control inside an UpdatePanel as shown below:
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
    <ContentTemplate>
        <asp:Label ID="lblDisplayDate" runat="server" Text="Label">asp:Label>
         <asp:Button ID="btnPostback" runat="server" onclick="btnPostback_Click"
        Text="ClickMe" />
    ContentTemplate>
asp:UpdatePanel>
div>
When you now run the application and click on the button, you will observe that the label is updated with the new time (which means the postback occurred), however the color of the label does not turn to red. This is because when using an Update Panel, the JavaScript that is dynamically added to the page using ClientScript.RegisterStartupScript() does not execute.
Solution:
Use the ScriptManager.RegisterStartupScript(). If you take a look at the methods of the ScriptManager class, you will observe that the methods to register client script to the page using the ClientScriptManager class, are also present in the ScriptManager class. So modify the code as shown below:
C#
protected void btnPostback_Click(object sender, EventArgs e)
{
    System.Text.StringBuilder sb = new System.Text.StringBuilder();
    sb.Append(@"");

    ScriptManager.RegisterStartupScript(btnPostback,this.GetType(), "JSCR", sb.ToString(),false);

}
VB.NET
Protected Sub btnPostback_Click(ByVal sender As ObjectByVal e As EventArgs)
      Dim sb As System.Text.StringBuilder = New System.Text.StringBuilder()
      sb.Append("")

      ScriptManager.RegisterStartupScript(btnPostback,Me.GetType(), "JSCR", sb.ToString(),False)

End Sub

Note 1: Observe that the last parameter to RegisterStartupScript is set to 'false'. This prevents us from inserting the

Ajax in Asp.net



Ajax Overview:-

·         AJAX = Asynchronous JavaScript and XML.
·         AJAX is not a new programming language, but a new way to use existing standards.
·         AJAX is the art of exchanging data with a server, and update parts of a web page - without reloading the whole page.
·         AJAX is a technique for creating fast and dynamic web pages.
·         AJAX allows web pages to be updated asynchronously by exchanging small amounts of data with the server behind the scenes. This means that it is possible to update parts of a web page, without reloading the whole page.
·         Classic web pages, (which do not use AJAX) must reload the entire page if the content should change.
Now let us see how this ajax is sending the request to the server and getting the response from the server
AJAX is based on internet standards, and uses a combination of:
  • XMLHttpRequest object (to exchange data asynchronously with a server)
  • JavaScript/DOM (to display/interact with the information)
  • CSS (to style the data)
  • XML (often used as the format for transferring data)
The XMLHttpRequest Object
·         All modern browsers support the XMLHttpRequest object (IE5 and IE6 uses an ActiveXObject).
·         The XMLHttpRequest object is used to exchange data with a server behind the scenes. This means that it is possible to update parts of a web page, without reloading the whole page.
Create an XMLHttpRequest Object
·         All modern browsers (IE7+, Firefox, Chrome, Safari, and Opera) have a built-in XMLHttpRequest object.
·         Syntax for creating an XMLHttpRequest object:
xmlhttp=new XMLHttpRequest();
·         Old versions of Internet Explorer (IE5 and IE6) uses an ActiveX Object:
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");

Send a Request To a Server
To send a request to a server, we use the open() and send() methods of the XMLHttpRequest object:
xmlhttp.open("GET","ajax_info.txt",true);
xmlhttp.send();

Method
Description
open(method,url,async)
Specifies the type of request, the URL, and if the request should be handled asynchronously or not.

method: the type of request: GET or POST
url: the location of the file on the server
async: true (asynchronous) or false (synchronous)
send(string)
Sends the request off to the server.

string: Only used for POST requests

The responseText Property
If the response from the server is not XML, use the responseText property.
The responseText property returns the response as a string, and you can use it accordingly:
Example
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
The onreadystatechange event
When a request to a server is sent, we want to perform some actions based on the response.
The onreadystatechange event is triggered every time the readyState changes.
The readyState property holds the status of the XMLHttpRequest.
Three important properties of the XMLHttpRequest object:

Property
Description
onreadystatechange
Stores a function (or the name of a function) to be called automatically each time the readyState property changes
readyState
Holds the status of the XMLHttpRequest. Changes from 0 to 4:
0: request not initialized
1: server connection established
2: request received
3: processing request
4: request finished and response is ready
status
200: "OK"
404: Page not found
In the onreadystatechange event, we specify what will happen when the server response is ready to be processed.
When readyState is 4 and status is 200, the response is ready.
Now we got an idea what is ajax and how to get the data using ajax.  Now we will see how this ajax can be used in our asp.net. Let us see with an example.
1.      Create a New Website.  default.aspx page will be opened as default.
2.      Add a Jscript i.e., Java script file to our project.
3.      Add the following code to it.

    function GetXmlHttpObject(handler)
    {
          var objXmlHttp = null
          if (navigator.userAgent.indexOf("Opera") &gt;= 0)
          {
              alert("This example doesn't work in Opera")
              return
          }
          if (navigator.userAgent.indexOf("MSIE") &gt;= 0)
          {
              var strName = "Msxml2.XMLHTTP"
              if (navigator.appVersion.indexOf("MSIE 5.5") &gt;= 0)
              {
                  strName = "Microsoft.XMLHTTP"
              }
              try
              {
                  objXmlHttp = new ActiveXObject(strName)
                  objXmlHttp.onreadystatechange = handler
                  return objXmlHttp
              }
              catch (e)
              {
                  alert("Error. Scripting for ActiveX might be disabled")
                  return
              }
          }
          if (navigator.userAgent.indexOf("Mozilla") &gt;= 0)
          {
              objXmlHttp = new XMLHttpRequest()
              objXmlHttp.onload = handler
              objXmlHttp.onerror = handler
              return objXmlHttp
          }
      }

4.      The above method creates and returns the xmlhttpobject by assigning an event handler to the object.
5.      Add the following method to the above js file.
    function stateChanged()
    {           
          if (xmlHttp.readyState == 4 || xmlHttp.readyState == "complete")
          {              
            document.getElementById("data").innerHTML=             xmlHttp.responseText;

              }
          }         
    }

6.      The above (stateChanged()) method is the handler which invokes when the response from the server is obtained.
7.      Add the following method to the same js file.
    function GetData()
    {           
          var url = "default.aspx?qstring=1";
          xmlHttp = GetXmlHttpObject(stateChanged);
          xmlHttp.open("GET", url, true);
          xmlHttp.send(null);       
    }
8.      This is the main function which we can call it at any event or any time according to our requirement.  Here we are passing the Query String to the default.aspx page and by using that string the whole manipulation will done at backend.
9.      Now add this js file to the page in the head part.
10.  Now we have completed the Ajax coding. Only the thing we have to do is, writing the backend coding for getting the data from the database.
11.  Now open the code file and do the following changes to the code in the  pageload event:

using System;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Data.SqlClient;
using System.Text;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (Request.QueryString["qstring"] != null)
        {
            SqlConnection con = new SqlConnection("");
            string select = "select * from Data_Capture_Personal_Det";
            con.Open();
            SqlCommand cmd = new SqlCommand(select, con);
            SqlDataReader dr = cmd.ExecuteReader();
            StringBuilder sb = new StringBuilder();
            sb.Append("
");
            while (dr.Read())
            {
                sb.Append("
");
                sb.Append("
");
                sb.Append("
");
            }
            con.Close();
            sb.Append("
First Name :" + dr[4].ToString() + "
Last Name :" + dr[5].ToString() + "
Middle Name :" + dr[6].ToString() + "
");
            Response.Write(sb);
            Response.End();
        }

    }


12.  Now above is your code page and below is your aspx page.

&lt;%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %&gt;

DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;

&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
&lt;head runat="server"&gt;
    &lt;title&gt;Untitled Pagetitle&gt;
    &lt;script src="JScript.js" type="text/javascript"&gt;script&gt;
head&gt;
&lt;body&gt;
    &lt;form id="form1" runat="server"&gt;
    &lt;div&gt;
    &lt;input type="button" value="GetData" onclick="GetData();" /&gt;
    div&gt;
    &lt;div id="data"&gt;
   
    div&gt;
    form&gt;
body&gt;
html&gt;

13.  Now run project by pressing F5 and click the button. The data will be displayed in the table format without a postback.
14.  See here we are seperating the functions accroding the the querystring which we pass for the respective data in the codebehind. .i.e., we are getting the data by using the querystring.
Note: The query string will not be visible in the addressbar.