Using Custom Lists in C#

22 03 2010

Recently I needed to retrieve information from a database and store it during runtime so that I could do some data manipulation and then present the data in a PDF file. When doing something like this, I find it very useful to use a custom list. I create a class that has all the properties I require, and then I create a list using this class as it’s type. All my data can then be stored neatly in this list and it’s easy to keep track of everything. Here’s some code to show how I do this.

1:Create your class…

private class RowForPDF
{
public string FirstName;
public string Surname;
public string PercCompleted;
public string CompletionDate;
public RowForPDF(string firstName, string surname, string percCompleted, string completionDate)
{
this.FirstName = firstName;
this.Surname = surname;
this.PercCompleted = percCompleted;
this.CompletionDate = completionDate;
}
public RowForPDF(string surname, string firstName)
{
this.Surname = surname;
this.FirstName = firstName;
}
}

As you can see, in my class I have overloaded it so I can have different types of my class depending on what my list is needed for.

2: Declare your list…
private List<RowForPDF> usersCompleted = new List<RowForPDF>();
private List<RowForPDF> userList = new List<RowForPDF>();

3: Add data to your list…
usersCompleted.Add(new RowForPDF("Sarah", "Williams", "52", "22/03/2010"));
userList.Add(new RowForPDF("Williams", "Sarah"));

You then have all your data stored in lists. Woop! And accessing them is nice too. For example, if I wanted to loop through each user in userCompleted and store some of their information in userList, I could do it like this…

for(int i = 0; i < usersCompleted.Count; i++)
{
userList.Add(new RowForPDF(usersCompleted[i].Surname, usersCompleted[i].Firstname));
}

Also when you’ve finished with the data in the list, you can use the Clear() method and it will remove all elements from your list.

So there they are, aren’t they beautiful?

Advertisements




Save a PDF to a byte array using PDF Sharp/MigraDoc

9 03 2010

After looking at my blog stats since putting up my post about combining 2 PDF’s using PDF sharp, I see that a lot of people are coming here when searching for the above. So although it is in my previous post amongst the combining code, I thought I’d post another little code snippet specifically for saving the PDF to a byte array using MigraDoc/PDFSharp.

So the following code assumes I have created a Document object called pdfDoc and formatted it and populated it as required.

byte[] fileContents = null;
using(MemoryStream stream = new MemoryStream())
{
pdfDoc.Save(stream, true);
fileContents = stream.ToArray();
}

So I am saving the PDF document to a memory stream, rather than a physical file location. I can then use the ToArray() function on the memory stream to give me my byte array. I personally then save this to my database as a VARBINARY.

So there you go. A PDF saved as a byte array. Enjoy!





Combining 2 PDF Documents into 1 with PDFSharp

4 03 2010

After looking at the example of how to do this on the PDF sharp website, I wrote the following code to combine 2 existing PDF documents into one & send the new document back to the user to download. Both PDF documents existed as byte arrays (which I had retrieved from my database, reportPdfContents & certsPdfContents) so if you’re retrieving them from your file system, you will need to slightly alter the code.

MemoryStream msReport = new MemoryStream(reportPdfContents); //reportPdfContents is a byte array
MemoryStream msCerts = new MemoryStream(certsPdfContents); //certsPdfContents is a byte array
PdfDocument reports = PdfReader.Open(msReport, PdfDocumentOpenMode.Import);
PdfDocument certificates = PdfReader.Open(msCerts, PdfDocumentOpenMode.Import);
PdfDocument combinedOutput = new PdfDocument();
int repPageCount = reports.PageCount;
for (int i = 0; i < repPageCount; i++)
{
PdfPage page = reports.Pages[i];
page = combinedOutput.AddPage(page);
}
int certPageCount = certificates.PageCount;
for (int i = 0; i < certPageCount; i++)
{
PdfPage page = certificates.Pages[i];
page = combinedOutput.AddPage(page);
}
byte[] combinedContents = null;
using(MemoryStream stream = new MemoryStream())
{
combinedOutput.Save(stream, true);
combinedContents = stream.ToArray();
}
Response.ContentType = "application/pdf"; //set the MIME type here
Response.AddHeader("content-disposition", "attachment; filename=ReportAndCertificates.pdf");
Response.BinaryWrite(combinedContents);
Response.End();

If you are familiar with PDF Sharp and have already looked at the examples, I think this code is probably pretty self explanatory. If you want some more information though, on the PDF’s, saving to/reading from byte arrays or opening a file on the client side just leave a comment. I do check them quite often so I’ll probably reply fairly quickly!





Casting SqlParameter/Object as a Byte array

2 03 2010

I’ve just spent ages working this out, and all the time I was just making a silly mistake! So hopefully this may save someone else the pain! For anyone that doesn’t want to read the rest of the post, the code to do it is:

byte[] fileContents = (byte[])sqlParameters[3].Value;

I was saving a PDF file as a byte array and then inserting that to my database as a varbinary. I needed to be able to then get that varbinary back out of the database as a byte array, and open it without corrupting the information.

So casting is the obvious candidate. But I made a silly mistake and had the following:

byte[] fileContents = (byte)sqlParamters[3].Value;

Which caused a problem as I was trying to cast a single byte to a byte array. I then got all caught up in using the ToString() method on the parameter value and then converting it from a string to a byte array. It just kept getting corrupted!

When I actually sat back and thought about it, a SqlParameter is just an object. So a simple cast is all that’s required. When I took a step back, I realised my code should have been:

byte[] fileContents = (byte[])sqlParameters[3].Value;

See what I mean about it being a stupid mistake?! All I needed was the square brackets in the casting and now it works perfectly, giving me back my lovely PDF, uncorrupted!

Sometime problems aren’t as complicated as you first think and the easy solution is the right one 🙂





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.





String Formatting in C#

5 02 2010

I don’t have much to say in this post really. It’s all in the title and I’m going to point you to this brilliant post on SteveX Compiled. Whenever I need to check up on a string format, this is the place I go! 🙂

http://blog.stevex.net/string-formatting-in-csharp/





Permissions issues with DLL’s stored on network shared drives

29 06 2009

One of the main things I am currently working on is a windows service that watches for files, and when one is found uses the information in that file, to call a DLL that is stored on a different machine on the same domain on a network shared drive, to do the magic with the information in the file (we will say in this case the DLL was held on MachineA and the service was running on MachineB).

I was having a continuous problem with the following exception:

“Request for the permission of type ‘System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089’ failed.”

It took a lot of surfing the internet and forums, and a lot of book reading to finally find a solution that worked for us.

Due to the DLL being held on a different machine (MachineA), MachineB would not allow it to do anything outside of it’s own scope. For example, it has no access to the file system. Using the caspol utility (see here for information) I added a new url with full trust to the internet group on MachineB using the following command text:

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\caspol.exe -addgroup 1.3 -url file:\\ipAddress/folder/* FullTrust

After doing this I restarted my service, and it worked! The nasty security permissions exception went away and it worked as expected. Yey!