3D Pie Charts (in Web projects)

9 02 2010

I recently needed to create a 3D pie chart and save it to a file so I could use the image to save to a PDF. I found the following tutorial / code library (which you’ve probably found long before finding this) which is fantastic http://www.codeproject.com/KB/graphics/julijanpiechart.aspx

However this is created for Windows Forms, and I was using this class with a web project. In the comments, there is some code given by the author in order to be able to save the file. Perfect! Unfortunately not if you’re using it in a web project, as this code will only work in Windows forms.

So here is how I got around it…

I used the PieChart3D object, intended for printing, as this gave me the opportunity to create a Bitmap object and use it’s graphics properties to pass to the PieChart3D.Draw method. This in turn means that when you call the Draw method passing the Bitmap’s graphics properties, it will draw to the Bitmap object. The Bitmap object has a Save method that can be used to save the file either temporarily or permanently.

Here’s my code…

private void DrawPieChart(decimal[] values)
{
//Set the properties of the pie chart
PieChart3D pie = new PieChart3D(10, 10, 200, 100, values, 0.15F);
pie.Colors = new System.Drawing.Color[] { System.Drawing.Color.DarkSeaGreen, System.Drawing.Color.LemonChiffon, System.Drawing.Color.Orange };
pie.Texts = new string[] { String.Format("{0}%", values[0].ToString()), String.Format("{0}%", values[1].ToString()), String.Format("{0}%", values[2].ToString()) };
pie.SliceRelativeDisplacements = new float[] { 0,0,0 };
pie.InitialAngle = -30F;
pie.FitToBoundingRectangle = true;
pie.EdgeColorType = EdgeColorType.DarkerThanSurface;
pie.EdgeLineWidth = 1;
pie.ShadowStyle = ShadowStyle.GradualShadow;
//Save the pie chart to a bitmap
Rectangle bounds = new Rectangle((int)pie.X, (int)pie.Y, (int)pie.Width + 30, (int)pie.Height + 30);
Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height);
Graphics grph = Graphics.FromImage(bitmap);
grph.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
grph.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
pie.Draw(grph);
pie.PlaceTexts(grph);
string tmpFilename = System.IO.Path.GetTempFileName();
bitmap.Save(tmpFilename);
}

So the second part of the code is what we’re concentrating on here. Firstly you create a bounding rectangle using the X & Y position and width and height of the pie chart. Using this rectangle, you can create a Bitmap that will be the correct size for your pie chart. You can then create Graphics from the Bitmap using the static Graphics method FromImage, passing in the Bitmap you have created. You then set the CompositingQuality and InterpolationMode (I don’t think this is absolutely necessary, however it is done in the original example, and I think it’s worth doing to get a high quality pie chart in your Bitmap). Using the Graphics you have just created from the Bitmap, you can now call the Draw method for the PieChart3D object, passing in these graphics (I also call place texts so it will show the percentages on each pie slice). For my use, I only needed a temporary file save (as I was then putting the file into a PDF and saving that). You could build a permanent file name if required instead of using GetTempFileName. Then you can call your Bitmap objects Save method and there you have it. Your pie chart, saved into a Bitmap from a Web Form project.

Advertisements




SQL Injection & Cross-Site Scripting (XSS)

23 06 2009

Today saw the need for me to test a current web application I’m working on for SQL Injection and Cross-Site Scripting. Although I was aware of both, I’d never had to test for them before. So in order to test for them, I had to learn how to do them first. I’m going to keep this post basic, as I found quite a few very useful pages & articles which I will link to at the end.

SQL Injection:

When creating or updating a database table, in my web application I am going through a Data Access Layer (DAL). I always use paramaterised queries as a rule, as I was aware that this was important security wise. To test SQL injection capabilities on my web application, I created a new table in my database called TestTable. Then I went to a web form that ultimately runs the UPDATE command on my database. In the ‘Description’ text fields, I inserted the following text
'; DROP TABLE TestTable --'
Which could result in the SQL code being
UPDATE NameTable
SET Name = 'Me', Description = ''; DROP TABLE TestTable --'
WHERE Id='1'

Obviously very dangerous code! Luckily, due to my DAL and parameterised queries, it took the text as literal text and not executable text and updated the database as expected, but with
'; DROP TABLE TestTable --'
as the description for the name ‘Me’. As I said, this is a basic explanation, there are also tests you should do on a login. I’m using a customised version of the .Net Membership API on my web application, in which case it was already accounted for. However, if you have written you’re own membership authentication, you should definitely test it for SQL injection.

The links I found useful for SQL injection as promised are:
http://msdn.microsoft.com/en-us/library/ms998271.aspx
http://www.sitepoint.com/article/sql-injection-attacks-safe/

Cross-Site Scripting (XSS):

If you are using Response.Write in your ASP.net pages, you are definitely vulnerable to XSS, also if you are using query strings. Even if you’re not, I would still recommend testing for any vulnerabilities. In order to test, I used some simple Javasript to pop up an alert box. I then pasted this on to the end of my url, i.e. “www.mywebsite.co.uk/login.aspx?’insert javascript here'” and pressing enter. If you get a pop up box with the text you gave to your Javascript alert command, then that’s bad! ASP.net handled my error with HttpRequestValidationException and didn’t carry out any of the Javascript, this is good! I tried the same thing when logged into my website, and also entered the Javascript in a text box on a form and submitted it. Again .Net handled it for me using a HttpRequestValidationException. All is well.

The links I found useful for Cross-site scripting as promised are:
http://en.wikipedia.org/wiki/Cross-site_scripting
http://www.sitepoint.com/article/cross-site-scripting/

Conclusion:

I’m pretty happy with how my tests went. I am however going to add some extra validation checks on my text boxes anyway, make sure all UPDATE, INSERT and DELETE commands are carried out via stored procedure and also make sure my user for connection to the database can only execute required stored procedures and select statements (that are parameterised) and cannot do any direct table access.

As I mentioned at the beginning of the post, I am new to the in’s and out’s of SQL Injection and XSS, so my understanding on some points may be a little off! If anyone who reads this thinks I’m wrong in something I’ve said, or can add anything to anything I’ve said, please comment because I would like to learn more about this subject.





Finding a control in a GridView that is DataBound

23 03 2009

I have a GridView that is databound to my database via a data access layer. On the end of the grid view, I have added a check box:

<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="chkError" runat="server" />
</ItemTemplate>
</asp:TemplateField>

A user is able to select one or more check boxes on rows within the GridView, and click a button to delete the selected row. In order for them to be able to do this, I need to go through each row in the GridView, find which ones are selected, and call my method to delete the row/rows.

My main problem was encountered trying to find the check box! As it is created dynamically, the C# code cannot see it until runtime. I got it working using the following code:

foreach (GridViewRow row in grdErrorAlert.Rows)
{
CheckBox ErrorCheck = (CheckBox)row.FindControl("chkError");
if (ErrorCheck.Checked)
{
//Delete this row!
}
}

The important line of code is:

CheckBox ErrorCheck = (CheckBox)row.FindControl("chkError");

This looks in the current row of the GridView, and finds the control “chkError” that is on that row. It then casts it as a check box and assigns it to a new instance of the check box ErrorCheck.





Are you sure you want to do that? Pop-up boxes with ASP.net web applications.

29 01 2009

My current project required that when a user tried to delete something, they would get a warning, that deleting that would delete other things to and offer them the option to proceed or cancel. There are many ways to do this, the best way I found to do it was using the following code:

Response.Write("<script>var result=confirm('Are you sure you want to delete this project? Doing so will also delete all units and tests associated to this project. Click OK to proceed, or Cancel to return to the Project Maintenance screen.');if(result){window.document.location.href='SubmitProject.aspx';}else{window.document.location.href='ProjectMaintenance.aspx';}</script>");

So the Javascript function says:

show the confirmation box
if(result == 'Ok')
{
go to SubmitProject.aspx
}else{
return to current page ProjectMaintenance.aspx
}

This is a very hand bit of code that I will probably use quite a lot from now on!





Refreshing web application pages using C#

28 01 2009

This is something that should be simple, but there is no straightforward Page.Refresh strangely! This is best way I found to do it…

Response.AddHeader("REFRESH","0");

The zero in the second parameter is how long I would like it to wait before refreshing the page. For example, I used this code on a log out button:

protected void LogOut(object sender, EventArgs e)
{
Session.Abandon();
Response.AddHeader("REFRESH", "0");
}

So when the user clicks “Log Out” the Session is abandoned, and the page is refreshed instantly, sending the user back to the log in page.

I also used this code in another application, where I needed to call a stored procedure in the database and then refresh and redirect the page. It was originally happening too quickly, so I used the following code.

Response.AddHeader("REFRESH", "2;URL=viewinvoice.aspx?tid=" + TID);

So there you go, there are probably a lot more funky things that can be done with Response.AddHeader, but for me, it is the best way to refresh a page I have come across so far!





Changing timeouts for websites/web applications

7 01 2009

As the result of a recent request, I was required to change the timeout on one of the web applications I work on.

From researching this subject, I have found there are 3 timeouts used in the web.config file.

  1. forms timeout
  2. sessionState timeout
  3. cookie timeout

My web application only uses the first 2 of these 3 timeouts. The asp.NET default value for both of these is 30 minutes.  I changed both of these values to 60 minutes. However my web application was still timing out after 30 minutes. Confusion ensued!

After more research, I found there is also a timeout of sorts on the Application Pool you are using (set in IIS).  In the first tab of the properties, Recycling, there is an option to “Recycle worker processes (in minutes)”. Mine was set to 1740 minutes, so this wasn’t my problem, but worth a mention I feel as it could have been causing my problem.

I then decided to try adding another option into my web.config file. I had already added:

<authentication mode="Forms">
<forms timeout="60" />
</authentication>

So I then added:

<authentication mode="Forms">
<forms timeout="60"
slidingExpiration="true" />
</authentication>

The slidingExpiration property then comes with a small problem of it’s own. In MSDN’s words:

“If the SlidingExpiration attribute is true, the timeout attribute is a sliding value, expiring at the specified number of minutes after the time the last request was received. To prevent compromised performance, and to avoid multiple browser warnings for users that have cookie warnings turned on, the cookie is updated when more than half the specified time has elapsed. This might result in a loss of precision.”

This basically means,  if you like me, set a timeout of 60 minutes, the expiration time of the authentication cookie is only updated if 30 idle minutes pass before the next request is made. So if a user signs in at 10:00 and then stays idle until 10:26 when they make a request, you would expect that the timeout would be reset and would next be expected at 11:26. In fact, because their request was made less than halfway into the timeout period, if they remain idle after their 10:26 request, the timeout will infact occur at 11:00.

There are various ways to get around this problem. I personally chose to live with it!

Even more research then uncovered there is another timeout of sorts if you are using the SqlProvider as your defaultProvider:

<membership defaultProvider="SqlProvider">

Another property that can be determined here is as follows:

<membership defaultProvider="SqlProvider" userIsOnlineTimeWindow="60">

However, adding this property didn’t solve my problem either. So I removed it again!

After forum posting and more internet trawling, I found a snippet of code that was different to my own. Where I had added:

<sessionState timeout="60" />

The snippet of code I found was:

<sessionState mode="InProc" timeout="60" />

So I added in the mode and hey presto! It works!

So in summary, in order to change the timeout of my web application, I added the following lines to my web.config file:

<system.web>
<sessionState mode="InProc" timeout="60" />
<authentication mode="Forms">
<forms timeout="60" slidingExpiration="true" />
</authentication>
</system.web>