Thursday, November 15, 2007

Some tips

Some tips:

Tip #1:

sometimes browsers dont support Javascript or the users purposely or accidently enable/disable javascript
in a website.
If your website uses many javascripts, then it is a good idea to inform a friendly message if Javascripts
is turned off or not supported.

There are easy ways to do this. one way to check is use a hidden field in the page, set its initial
value to true,then call the javascript from onload. change the hidden field value to false. check again
for the hiddenfield value. if it is true, then javascript is either not enabled or supported

Another easy way to do this is to add the html tag below: Please add the < and > i.e opening and closing tags for html

noscript
meta http-equiv='refresh' content='0;url=http://localhost/JavascriptError.aspx'
noscript

This tag will check if JS is enabled or not and redirect to a Custom JSError page.


To check if JS is supported by a browser, use Request.Browser.Javascript in c#

Tip #2:

If you want to check browser version using C# code,

if (!IsPostBack)
{
if (Request.Browser.Browser == "IE")
{
if (Request.Browser.MajorVersion < 6)
{
//Redirect to custom page to download IE 6 or more
}
}
else if (Request.Browser.Browser == "Firefox")
{
if (Request.Browser.MajorVersion < 2)
{
Response.Redirect("http://www.mozilla.com/en-US/firefox/");
}
}
}


Tip #3:

When you develop a site, you generally use tables/divs and spans...if you use .NET's ajax capabilities, you need to wrap everything that should be ajax enabled inside a updatepanel's contentpanel

What happens when you do this is by default is, all html tags gets capitalized and there is the annoying red squiggly lines..

The cause for this error is, in your web.config look for this tag...and change the tagprefix from
default asp to anything else... (Please the opening and closing tags for the following)

(opening tag) controls (closing tag)
(opening tag) add tagPrefix="ajax" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/ (closing tag)

(opening tag)controls / (closing tag)

and now change the to . All your errors should be gone.


Tip #4:

The required field Validators and other .NET validators didnt work for us due to a missing update or hotfix on the server. and we decided to extend the validators by using Validators.dll file we got
from a Microsoft blogger Matt Gibbs.

Link to the page is:
http://blogs.msdn.com/mattgi/archive/2007/01/23/asp-net-ajax-validators.aspx

hot fix:

http://blogs.msdn.com/mattgi/archive/2007/05/12/validators-update-available.aspx


Tip #5:

This piece of code can be used to trap enter key press from any page.

public void SetDefaultButton (TextBox control)
{
control.Attributes.Add("onkeydown", "if(event.which || event.keyCode){if ((event.which == 13) || (event.keyCode == 13)) {return false;}} else {return true}; ");
}


public void FindTextBoxesForEnterKeyPress(Control ParentControl)
{
// Init the name of the control
foreach (Control childControl in ParentControl.Controls)
{
if (childControl is TextBox)
{
SetDefaultButton((TextBox)childControl);
}
else
{
if (childControl.HasControls())
{
// Make a recursive call to loop through the child's children protected void
FindTextBoxesForEnterKeyPress(childControl);
}
}
}
}


Tip #6:
//Used to get the current instance of the scriptmanager and set the focus

//setting focus doesn't work if tried to access it directly due to ajax capabilities

ScriptManager scrMgr = ScriptManager.GetCurrent(this.Page);

scrMgr.SetFocus(this.textbox1.ClientID);

Tip#7:
private void CustomValidationSummary()
{
foreach (Control currentControl in this.Page.Validators)
{
IValidator currentValidator = currentControl as IValidator;
if (currentValidator != null)
{
if (!currentValidator.IsValid)
{
Label currentValidationMessage = new Label();
currentValidationMessage.Text = currentValidator.ErrorMessage;
//Do something with the label here
lblLoginError.Text = lblLoginError.Text + "
" + currentValidationMessage.Text +
";
LabelError.Text = LabelError.Text + "
" + currentValidationMessage.Text+"
";
}
}
}
}


Tip #8

A potentially dangerous Request.Form value was detected
from the client user Page attribute validaterequest = false
and handle it explicitly


A potentially dangerous Request.Form value was detected
from the client (ResultInput="...="1.0"? ResultData
xmlns:xs...").
Description: Request Validation has detected a
potentially dangerous client input value, and processing
of the request has been aborted. This value may indicate
an attempt to compromise the security of your
application, such as a cross-site scripting attack. You
can disable request validation by setting
validateRequest=false in the Page directive or in the
configuration section. However, it is strongly
recommended that your application explicitly check all
inputs in this case.

Thursday, August 23, 2007

Add ASP.NET AJAX Features to an Existing Web Application:

First you must install ASP.NET 2.0 AJAX Extensions 1.0. To do this go to http://asp.net/ajax/downloads/ and you will find link to Download this. If you need to take advantage some other extensions you may want to download the AJAX Control tool kit.

This installation will add System.Web.Extension.dll to your GAC.

1. Load an existing .NET Web application
2. you need to Modify the web.config with few important sections.
3. The easiest way to do that is, create a "Ajaxenabledwebsite" by opening a new instance of Visual studio
and open the Web.config. Copy these sections:

<configsections> element,
<controls> tag wires the tagPrefix all of the things that live in the server side controls for the microsoft Ajax extension
replace the entry - add's assemby to System.web.Extensions

<httphandlers>

I didnt copy this portion and Ajax worked fine. so this should be fine, but the video suggested to copy
them too
<httpmodule>
<system.webserver>
<system.web.extensions>

4. Now go to your webPage's design and drag&drop the scriptManager on to the page.
5. There can be only one ScriptManger for a ASP.NET Page that is going to use Ajax and it is a must

6. Drag and drop a UpdatePanel and move all the content you want to ajax enable into this

7. Include Trigger functions to specify on which event you will need to fire the ajax

quick link for video demo of the same article

Thursday, August 16, 2007

Health Monitoring .NET 2.0

Health Monitoring .NET 2.0:

Probably this is known information,but health monitoring in .NET 2.0 reduces a
whole lot of coding.If it were to be done in 1.1 it requires a lot of developer effort.

Ok,diving into what is healthMonitoring: It monitors a running Application and does logging like
Any errors, any failures,restarts, along with custom events too (involves some coding)

Actually just by configuring the web.config, you can log events in application event viewer
By configuring the Sql Server database aspnetdb, you can log events in the database without a
single line of code.


A simple example of healthMonitoring:

Use this code snippet below under tag in web.config file

create a simple object reference not set error in your code.

Build the application, run it to see the Server error page.

Now open ControlPanel-->AdministrativeTools -->EventViewer -->Application and look for the
most recent entry. you will see the log information of the error.


<healthmonitoring>
<providers>
<clear>
<add name="EventLogProvider" type="System.Web.Management.EventLogWebEventProvider">
</add>

<eventmappings>
<clear>

<!--Log all default error events-->
<add name="All Errors" type="System.Web.Management.WebBaseErrorEvent">

</add>
-->
<rules>
<clear>
<!--Logs all webbaserrors to windows event log-->
<add name="All Errors Default" eventname="All Errors" provider="EventLogProvider" mininstances="1" maxlimit="Infinite" mininterval="00:00:00">
</add>
</clear>
</healthmonitoring>


HealthMonitoring Explained in detail:


The health monitoring tag in web.config goes under the .

<system.web>.
<healthmonitoring>
......
......

</healthmonitoring>
</system.web>

There are five major subsections to health monitoring:

They are:

providers
profiles
bufferModes
eventMappings
rules

providers: They provide the functionality for an API. It is a contract between an API and
the business logic/Data Abstraction layer. [From MSDN].

healthMonitoring providers, there are several of inbuilt providers
The default providers available are SqlWebEventProvider,EventLogProviders,WmiWebEventProvider

<providers>
<clear>
<add name="SqlWebEventProvider" connectionstringname="YourConnectionString" maxeventdetailslength="1073741823"><!-- This the maximum length of the event details -->
buffer="true" <!-- Default is false, if you set to true, you have configure the buffer mode property-->
bufferMode="Analysis"
type="System.Web.Management.SqlWebEventProvider,System.Web,
Version=2.0.0.0,Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a"/>

<add name="EventLogProvider" type="System.Web.Management.EventLogWebEventProvider">
</add>


bufferModes: This is used to configure the buffering property of a provider. This is configured
to reduce performance impact and overhead of recording events.

The different bufferModes are CriticalNotification,Notification,Logging and Analysis
You can also configure your own custom bufferMode

<buffermodes>
<add name="Analysis" maxbuffersize="1000" maxflushsize="100" urgentflushthreshold="100" regularflushinterval="00:05:00" urgentflushinterval="00:01:00" maxbufferthreads="1">
</add>


name property above is used by the tag to reference it in the bufferMode property
maxBufferSize: maximum number of events that can be buffered by a provider before flushing
them and writing them to store

In our example above, I have used 1000 as the maximum number of events

maxFlushSize: How many events to flush at one time. this value can be between 1 and maxBufferSize

In our example above, I have used 100 events to be flushed at one go!

urgentFlushThreshold: minimum number of events after which the flush should occur


regularFlushInterval: This is the time interval per flush. Its value cannot be zero.


Every five minutes the flush would happen and be written to database


urgentFlushInterval:minimum time between flushess. I have used 1 min

maxBufferThreads: This is the maximum number of threads used for flushing.


profiles: I have not used this property in healthMonitoring. From what I have read,
they are used to determine how each event is collected and raised to the providers.
we have 2 providers by default.
They are Critical and Default
You can also write your custom profile.


eventMappings:

they specify which events you want to monitor. For example you can mention "All Events" happening,
or all "All Errors" , or "Heartbeats" or any custom event you would like to raise.
eventMappings can be done like the below:


<eventmappings>
<clear>
<!--Log all default error events-->
<add name="All Errors" type="System.Web.Management.WebBaseErrorEvent">
startEventCode="0"
endEventCode="2147483647"/>
</add>


rules: These are the part of the healthMonitoring which specify which events have to be logged
through which provider.

so for example:

<rules>
<clear>

<!--Logs all webbaserrors to windows event log-->
<add name="All Errors Default" eventname="All Errors" provider="EventLogProvider" mininstances="1" maxlimit="Infinite" mininterval="00:00:00">
</add>


This one helps us to log all the errors occured, uses the reference to the event name "All Errors"
and uses the provider "EventLogProvider" to log any error in the application to the Event Log viewer


Next article :how to configure your sqlserver database to log events.


Here are few good links for further reading:

how to raise custome events using healthMonitoring: http://msdn2.microsoft.com/en-us/library/ms998306.aspx
FAQ's of healthMonitoring: http://blogs.msdn.com/erikreitan/archive/2006/05/22/603586.aspx





Thursday, March 22, 2007

xmlHttpRequest

I am always fascinated with google! How did they know about ajax and stuff ahead and came up with Google suggest kind of feature..Ajax is cool. did you know, even Gmail is ajax based.. but, have you ever thought about the architecture behind ajax? we have so many toolkits nowadays which is ajax enabled hiding what is going on behind...but its always good to understand architecture..

I am not going to explain it all as this article does. the crux is this object xmlHttpRequest.
Have fun reading this article. Thanks to the author for a wonderful explanation.

http://www-128.ibm.com/developerworks/xml/library/wa-ajaxintro1.html
http://www-128.ibm.com/developerworks/xml/library/wa-ajaxintro2/index.html

Wednesday, February 21, 2007

GridViews with DataTables - Part II

Part II:

Now to handle Edit,update,cancel and delete operations in the Gridview..we will do the following....

Edit The row: To do an edit on the row, we need to write the event on RowEditing. If you dont know where to find this, click on the GridView, click properties.on the properties tab you will see a small Flashing symbol(On the top).Double click on the event called RowEditing and it will open the code below.

protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
GridView1.EditIndex = e.NewEditIndex; //This will enable the row clicked in the Grid into an editable mode.
if (Session["tables"] != null)
{
GridView1.DataSource = Session["tables"];
GridView1.DataBind();
}
}

What we do above is, we set the EditIndex to be the currently clicked row in the Grid and bind the Grid again with our Datasource.

Cancel the Edit Option: The most easiest of all, Write the event in RowCanceling.

protected void GridView1_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
GridView1.EditIndex = -1; //Restore to normal.
if (Session["rows"] != null)
{
myDatatable = (DataTable)Session["rows"];
GridView1.DataSource = myDatatable;
GridView1.DataBind();
}
}

Update a Grid to a datatable: The event associated to do this RowUpdating. what we do here is, we find the row that was clicked to do an update.then, find the textbox value and bind it back to the grid. and we also set the EditIndex to -1 so that the Grid looks normal. I had difficulty in finding how to identify the textbox since i didnt create any template column


protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
GridViewRow row = GridView1.Rows[e.RowIndex]; // This statement finds the row that was clicked.
GridView1.EditIndex = -1; // Change the Grid to Normal view.

if (row != null)
{
TextBox t = (TextBox)row.Cells[1].Controls[0]; //This will find the control in Cells[1] in the grid and since we know it is a textbox //we are casting it to a temporary textbox t

myDatatable = (DataTable)Session["tables"]; //Get the old datatable from the session variable

//Till the end of the datatable, we traverse till we find the DataTable's row and the row in the grid are equal..and update the datatable with //the new value.
for (int i = 0; i less than myDatatable.Rows.Count; i++)
{
if (e.RowIndex == i)
{

myDatatable.Rows[i][0] = Convert.ToInt32 (t.Text); //Assign the textbox value to the current row.

Session["tables"] = myDatatable; //Set the new Datatable to the session

GridView1.DataSource = myDatatable;
GridView1.DataBind ();
}
}
}
}

Delete the Row : We are almost done.! just one more step.follow the comments next to the statements, straightforward stuff..

protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
GridViewRow row = GridView1.Rows[e.RowIndex]; // Find which row was clicked to delete?
if (row != null)
{
myDatatable = (DataTable)Session["rows"];
for (int i = 0; i less than myDatatable.Rows.Count ; i++)
{
if (e.RowIndex == i)
myDatatable.Rows.RemoveAt(i); //Remove that row.
Session["tables"] = myDatatable; //assign the new datatable to the session.

//Bind to the Grid again.! Everyone is happy !
GridView1.DataSource = Session["tables"];
GridView1.DataBind();
}
}
}
}

So we have done all the basic binding,update,edit,cancel,delete on a grid from a datatable. if you have any questions feel free to contact me on this particular topic.

Till then, Happy Coding :).

Tuesday, February 20, 2007

GridViews with DataTables - Part I

One of the most common questions, i come across on forums while using Gridviews with datatables,how do i do an edit, update delete if there is no SqlDataSource, or ObjectDataSource (Basically you have nothing to do with the DataBase) but instead you have specified your datasource to be a DataTable to bind the Grid. All the values in the Grid are built from a datatable. I had to do something exactly like this and with help on forums and some googling, I acheived this. Thought to share my 2 cents so that you can use it when you want a DataTable and have no database operations.

Firstly, Once you put a Gridview on the page, set the AutoGenerateColumns = true, and AutoGenerateEditButton = true and AutoGenerateDeleteButtons = true.

Now, in the code behind declare a new DataTable and new DataColumn for the DataTable. On the Page load event include this code.

public partial class Default: System.Web.UI.Page
{

//Declare a new DataTable and allocate memory
DataTable myDatatable = new DataTable();
// Declare a new DataColumn and allocate memory
DataColumn myDataColumn = new DataColumn();
//Add extraColumns if u need to in the DataTable and allocate memory
DataColumn myDataColumn2 = new DataColumn();
//Declare a new DataRow.
DataRow myDataRow;

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//Define the DataColumn's DataType.
myDataColumn.DataType = System.Type.GetType("System.Int32");
//Declare the Name of the column
myDataColumn.ColumnName = "Quantity";
// myDataColumn.ReadOnly = true; //Use this if you want the column to be //readonly, probably you wont need it.
//Add the column to the DataTable myDataTable
myDatatable.Columns.Add(myDataColumn);
//Add the DataTable into a Session variable for later usage.
Session["tables"] = myDatatable;
}
}
}

Ok, the above code will create a new Datatable with the column definitions and properties. now imagine you have a textbox and a submit button. Values entered in the textbox must get bound to grid, each time you click the button a new row has to be generated. To accomplish this follow the code below:

protected void BtnSubmit_Click(object sender, EventArgs e)
{

if (Session["tables"] != null)
{
//Retrieving the values from the session and assigning to our DataTable
myDatatable = (DataTable)Session["tables"];
//Create a new Row in the DataTable using the NewRow() method.
myDataRow = myDatatable.NewRow();

//The i'th Row's i'th column is assigned a value. In this case, we have only one column and each row is created on each button //click. so, i have specified the ColumnName and assigned the value from the TextBox.

myDataRow["Quantity"] = Convert.ToInt32(txKitQty.Text);
//Add the row to the DataTable
myDatatable.Rows.Add(myDataRow);
//Update the session with the new DataTable information
Session["tables"] = myDatatable;
// You can set the source to be the myDataTable or the Session variable, both are //same here
GridView1.DataSource = Session["tables"];
GridView1.DataBind();
}
}

So, now our Grid gets bigger and bigger on each button click with a value from the textbox. Since we already set the AutoGenerateEdit and Delete Buttons in the grid to be true, we can now see a Edit and Delete Hyperlinks on each row.

How do we do edit a row entered in the Grid . How do we update?Cancel?Delete a row?..and bind it back to the DataTable?

To be Contd.... Till then try this out and Happy coding.!

Monday, February 19, 2007

.NET 3.0

Since .Net 3.0 was realeased very recently..I was like, what the hell...I am still learning .Net 2.0 and dont know what i had missed in 1.1 Now it's 3.0 what's next for Microsoft??...

Googled a bit trying to know what is in .NET 3.0. In my very short attempt to gain something..I came across this blogspot

I could just say that, WPF will rock..how these people come up with these things...Though i dont know any technical aspects about 3.0's WPF, WCF...etc.etc..I am curious to know this stuff. Do you know any books, links which is like a tutorial to start learning this??
leave a comment.

Happy Coding :)

Saturday, February 17, 2007

Avoid Insert Errors.

A very common error which can occur when doing an insert into a database if you are using plain SQL statements instead of a stored procedure is when you don't take care of the common SQL injection mistakes..(SQL injection is a very huge topic and there are so many expert advice online which i am not going to discuss here).
Coming to the post, to avoid the error of sql statements when inserting records, The most common way of getting sql insert or update error is , when you write a query like the one below.

"Insert into UserDetails(UserName,Password) Values( ' " + txtUserName.Text + " ' ,' " + txtPassword.Text + " ' ) " ;

We have no control over what the user enters, Of course there are validators and we can keep a good check there..what if we missed certain conditions? What if the user enters in the provided textbox a value like this " I'll be there" or "C'mon guys"...basically any extra single quote that is not supposed be there...To avoid this error, one way is

txtUserName.Text.Replace(" ' "," ' ' ")


[Note: here any single quote is replaced with 2 single quotes and not a single double quote]

This will take care of any single quote errors. Of course,as told earlier there are other SQL injection problems, but this is one less error to take care of...

One other good way i have seen is have a class called RemoveBadChars which will be called first to kill unnecessary characters and then pass the variables to the stored proc or the insert statement...

Any other good practices,please leave a comment

Happy Coding :)

Friday, February 16, 2007

GridView Hyperlink Field.

We have done this in datagrids, suppose you need to click on a item in a gridview and provide detailed information about that item in a new page...one of the ways to do it is pass the value as a querystring to another page and retrieve it there. To accomplish this, all you have to do is,

1. Add a hyperlink field (in datagrids this was HyperlinkColumn).
2. Set the DataNavigateUrlFields to the parameter you want to pass in the querystring (In DataGrids this was DataNavigateUrlField.)
3. The DataTextField is the Field from the DataBase you are binding to the Grid. (it was the same in DataGrids)

paste the code below into ur gridview to make it work.

(Please include the starting <>asp:HyperLinkField HeaderText="AnyTextwillwork" DataNavigateUrlFields="ID" DataNavigateUrlFormatString="OrderDetails.aspx?OrderID={0}" DataTextField="ID"/>


Then you know the rest, use Request.QueryString["OrderID"].ToString() to retrieve the value in the next page..do your processes there..

hope this helps and comes handy.

Happy Coding :)

Thursday, February 15, 2007

Date in SQL

Hi,
Below is a a very few basic SQL server questions related to datetime in sql

1.how do you get todays date in sql?

2.if you need to get yesterdays date how will you do in sql?

3.by default sql date time datatype stores values in YY:MM:DD: hh:mm:ss:mss
but if you want to display a date in MM/DD/YY how will you do it?

4.what does a datepart function do?

You can get all the answers from sql server books online.

anyway, the answers to the above are

1. GetDate()
2.

USE pubs
GO
DECLARE @altstartdate datetime
SET @altstartdate = GetDate()
SELECT @altstartdate - 1 AS 'Subtract Date'


3. In the front end if you want to display the date in MM/DD/YYYY format: all you have to do is: DateTime.Now.ToString("yyyy-MM-dd")

In the query if you need to display a date in mm/dd/yy you need to convert it.

Use pubs
go
SELECT CONVERT(char(12), GETDATE(), 1)
Char(12) indicates that you need the date to be displayed as a char datatype.
GetDate() gets the current date.
the third parameter is the style. To display the date in mm/dd/yy format it is 1.
to display the full year you need to say 101..
there is a whole list, just search for date in sqlserver books online.

4. DatePart splits the date to display how you want it.
DATEPART ( datepart , date ) is the syntax.
you specify Datepart(yy,Getdate()) it will give you the yy portion of current date.

Happy Coding :)

Validation Tips

when you have a textbox and we enable TextMode Property = multiline, then MaxLength property does not work.
In order to have this feature, we have to either write a Regular expression or a custom control. I googled to find a regular expression that will do the task:

To limit characters(can have any characters) : ^\s*(\w\s*){1,250}\s*$
To limit only positive integers: \b\d+\b
To limit only alphabets: \b[A-ZA-z]+\b

Could come handy when u need it ..

http://regexlib.com/ is a good site for most of the regular expressions you will use.

Happy Coding :)