Thursday, November 12, 2009

Upload a large file using Fileupload control in asp.net

By default, the maximum size of a file to be uploaded to a server using the ASP.NET FileUpload control is 4MB. You cannot upload anything that is larger than this limit.

To change this size limit, you have to make some changes in the application's web.config:

in system.web change the following..

httpruntime executiontimeout="360" maxrequestlength="102400"

maxRequestLength - Attribute limits the file upload size for ASP.NET application.  The size specified is in kilobytes. As mentioned earlier, the default is "4096" (4 MB). Max value is "1048576" (1 GB) for .NET

executionTimeout - Attribute indicates the maximum number of seconds that a request is allowed to execute before being automatically shut down by the application. The executionTimeout value should always be longer than the amount of time that the upload process can take.

Sql Injection

Most of Developers used to write sql queries. But the problem here is "sql injection".

What is Sql Injection

SQL Injection happens when a developer accepts user input that is directly placed into a SQL Statement.
This can allow an attacker to not only steal data from your database, but also modify and delete it.

How Sql Injection works

For example you want to check USER ID and PASSWORD from database and you write the query as follows

select userid from tablename where userid='"+txtUser.Text+"' and password='"+txtPwd "'"

This is called dynamic query building,

suppose i enter values

txtUser -- kartheek


txtPwd -- chkartheek

query becomes

select userid from tablename where userid='kartheek' and password='chkartheek'

and gives output perfectly but the problem is...

suppose an attacker want to login into ur account he enters the text into the userid as follows..

txtUser -- yy' or 'a'='a'--


txtPwd -- xxxxx

then the query becomes as follows

select userid from tablename where userid='yy' or 'a'='a'-- 'and password='chkartheek'

see the query once here the query checks the condition " userid ='yy' or 'a'='a' " and after the " -- " will be commented

so condition works perfectly and attacker can loggin to your account.

This is what we called SQL INJECTION

How to avoid Sql injection

* Use parameterized queries (SqlCommand with SqlParameter) and put user input into parameters.

* Don't build SQL strings out of unchecked user input.

* Use stored procedures to encapsulate database operations.


SqlCommand cmd = new SqlCommand("select userid from tablename where userid=@userid and password=@password", con);



cmd.Parameters.AddWithValue("@userid", txtUserid.Text);


cmd.Parameters.AddWithValue("@password", txtPwd.Text);
 
This solves the sql injection.

Wednesday, November 11, 2009

Fastest way to get data from database is using SqlDatareader

As you know the difference between DATASET and DATA READER, most developers use DATASET with DATA ADAPTER to get large amount of data, but this is not efficient work to do. If number of users access data from database simultaniously Dataset and Data Table gives burden on server which may get slowdown. So to avoid this we need to use DATA READER.

Example :

SqlCommand cmd = new SqlCommand("select * from tablename",con);

con.Open();
SqlDataReader dr = cmd.ExecuteReader();
GridView1.DataSource = dr;
Gridview1.DataBind();
con.Close();

This is the way we use Data reader to assign data to gridview.
and one more way is using " IDataReader ".

Suppose you have a class file to access data, and you can't return datareader because if you once close datareader it losts data so we use IDatareader.

The following is a class file or DAL (Data Access Layer)

public class Class1

{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["conStr"].ToString());
public IDataReader getRecs()

{
SqlCommand cmd = new SqlCommand("select * from myfaq",con);
con.Open();
SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
return dr;
}

Here " getRes() " is a method returns object of type " IDataReader " and dr is the " SqlDataReader ".
to close connection after fetching all records we use " CommandBehaviour " class in " ExecuteReader " as shown above.
And the code in page is...

protected void Page_Load(object sender, EventArgs e)

{
Class1 cs = new Class1();     // class object
GridView1.DataSource = cs.getRecs();          // calling getRecs() method
GridView1.DataBind();
}

This is how we optimize the performance of data accessing from database using SqlDataReader.

Efficient Paging in Asp.net

Already we know the concept of paging in Asp.net, it is easier to do and faster in development.
But with built in gridview paging we have one problem that is each and every page load the it retrives entire records from the database. so it is burden on the server to get entire records each and every time from the database.
Inbuilt paging good for upto 100 records but if we have more than 100 record it is not good to impliment. so we need to develop a custom pagination for that.
Using the custom pagination we will get only the records which were displayed on that page only. It is good to give the load to Database server than our asp.net application. That is we need to write a Query using rownum with which we will get only the record in between certain rownumber, which solves our problem.

Steps to Impliment custom paging:

1. Get the total number of records from the database and devide the number of records by using our page size and use ceiling function to get next integer which gives our number of pages.

Example:


public void Gv_Custompaging()
{
SqlCommand cmd_count = new SqlCommand("select count(*) from tablename", con);
con.Open();
int i = Convert.ToInt16(cmd_count.ExecuteScalar());
con.Close();
i = Convert.ToInt16(Math.Ceiling(Convert.ToDouble(i/3)));
for (int c = 1; c <= i; c++)
{
LinkButton lb = new LinkButton();
lb.ID = "link" + c;
lb.Text = c.ToString();
lb.Command += new CommandEventHandler(lb_Command);
PlaceHolder1.Controls.Add(lb);
PlaceHolder1.Controls.Add(new LiteralControl(" "));
}
 getBind("1");
}



Here the code gets number of records into Number_Of_Recs, and which will be devided by our page size (10) gives number of pages after ceiling the fraction and which will be stored in Number_Of_Pages.
And that loop iterates for Number_Of_pages and creates a link button for each iteration and that link button is added to the Placeholder1 displays like following

1 2 3 4 5 and more..

here each link click calls a function lb_cmd() where we need to get data from database.


void lb_Command(object sender, CommandEventArgs e)

{
LinkButton link = (LinkButton)sender;
getBind(link.Text);
}


protected void getBind(string page)
{
SqlDataAdapter da = new SqlDataAdapter("Sp_GetPage", con);
da.SelectCommand.CommandType = CommandType.StoredProcedure;
da.SelectCommand.Parameters.AddWithValue("@page", page);
DataTable dt = new DataTable();
da.Fill(dt);
GridView1.DataSource = dt;
GridView1.DataBind();
}

Here the lb_cmd() calls the method getBind() which accepts a parameter page which is the page number we are going to display. getBind() method calls a procedure " Sp_GetPage " which takes a parameter @page.
and the stored procedure is...

CREATE PROCEDURE Sp_GetPage

@page int
as begin
set @page =@page-1
select rownum,field1,field2 from (select field1,field2,ROW_NUMBER() over (order by sno desc) as rownum from tablename f )
as newtablename where rownum between (@page*10)+1 and (@page+1)*10
end

This was the procedure and code used for Gridview custom paging

Welcome Post

Hi Dot net developers