Thursday 30 August 2007

ASP.NET - Random Key Generator

OK, you may need to generate a secure random key to maybe place in a database, or any other reason that you have. Here's a way I generate a secure case-sensitive string:

Add the following under Inherits System.Web.UI.Page:


Const minlength = 13
Const maxlength = 15
Dim m_rand As New Random



Now add a new function, like so:


Function GenerateKey()
Dim charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
Dim length As Integer
length = m_rand.Next(minlength, maxlength + 1)
Dim key As New StringBuilder(length)
Dim i
For i = 0 To length
key.Append(Mid(charset, m_rand.Next(0, Len(charset)), 1))
Next
Return key.ToString
End Function



Now all you need to do in your code is call GenerateKey() and it will return a unique key. Bear in mind that you can change the minimum and maximum length of the key by editing the const values that we added at the start.

Enjoy!

Monday 6 August 2007

ASP.NET - Save password value

If you create a textbox with a TextMode of Password, you will see that when the form is submitted, the value is lost out of the textbox. This is due to security reasons, but you can force it to keep the value by simply adding the following to the Page_LoadComplete event:



If Page.IsPostBack Then
Me.password.Attributes.Add("value", Me.password.Text)
End If



Just make sure you replace "password" with the name of your textbox.

ASP.NET - Dynamic Controls

Let's say you wanted to create a CheckBox for every row in a table. How do we create it? How do we reference it on a PostBack? There are many guides on how to do this but they are unclear and don't explain what happens.

If we create components via code, you may be unsure on how to reference it later, say in a buttons click. When they are created dynamically the problem is that the controls are lost on a PostBack thus code fails to execute and you can't get the Checked state or Text of say a TextBox control because they are no longer there.

How do we solve this? You MUST create all dynamic controls in the Page_Init event. This means that the controls will not be lost during a PostBack, thus you can reference them correctly.

Let's create 10 CheckBox controls on the page and then return their checked state when you push a button. The first thing to do is place a PlaceHolder control onto the page, in this example it will be left to its default name of PlaceHolder1. This will be a container for all of our dynamic controls.


dim i
for i = 0 to 9
Dim cb As New CheckBox
cb.ID = "cb" & i
cb.Text = "Dynamic Checkbox " & i
cb.EnableViewState = True
cb.Width = 300
PlaceHolder1.Controls.Add(cb)
PlaceHolder1.Controls.Add(New LiteralControl("< BR>"))
Next


In the example above we step through a loop and create 10 checkbox controls, each with a html break to seperate them and make it look tidy. Now all we need to do is get the state of every checkbox and here's how (place the following code within a button):



Dim results
Dim cb As Control
For Each cb In PlaceHolder1.Controls
If TypeOf cb Is CheckBox Then
If CType(cb, CheckBox).Checked Then
results = results & CType(cb, CheckBox).Text & " is Checked < BR>"
End If
End If
Next
response.write(results)


The above will simply check through all of the dynamic controls and list all the boxes that are checked via a simple response.write. You could code a Select All button simply by doing the following:



Dim cb As Control
For Each cb In PlaceHolder1.Controls
If TypeOf cb Is CheckBox Then
CType(cb, CheckBox).Checked = True
End If
Next


Easy! Hopefully you all understand the basics of working with dynamic controls now. The examples above have no limit on the amount of controls that are created and can easily be adapted to the amount of rows on a database, for example.

Thursday 2 August 2007

ASP.NET - LDAP Domain Information

Ever wanted to retrieve properties of a user from the domain? An easy way is through LDAP (providing the service is running).

Declare the following:


Imports System.DirectoryServices



Now place the following in your code, where appropriate:


Dim oroot As DirectoryEntry = New DirectoryEntry("LDAP://SERVER", "USERNAME", "PASSWORD")
Dim osearcher As New DirectorySearcher(oroot)
Dim oresult As SearchResultCollection
Dim result As SearchResult

Dim FINDUSERNAME = "jbloggs"

osearcher.Filter = "(&(objectCategory=person)(sAMAccountName=" & FINDUSERNAME & "))"
osearcher.PropertiesToLoad.Add("cn") ' username
osearcher.PropertiesToLoad.Add("name") ' full name
osearcher.PropertiesToLoad.Add("department") ' department
osearcher.PropertiesToLoad.Add("givenname") ' firstname
osearcher.PropertiesToLoad.Add("sn") ' lastname
osearcher.PropertiesToLoad.Add("mail") ' mail
osearcher.PropertiesToLoad.Add("initials") ' initials
osearcher.PropertiesToLoad.Add("ou") ' organizational unit
osearcher.PropertiesToLoad.Add("userPrincipalName") ' login name
osearcher.PropertiesToLoad.Add("distinguishedName") ' distinguised name
osearcher.PropertiesToLoad.Add("sAMAccountName") 'userlogin

Try
oresult = osearcher.FindAll()

dim username
dim fullname

For Each result In oresult
username = result.GetDirectoryEntry.Properties("cn").Value
fullname = result.GetDirectoryEntry.Properties("name").Value
Next
Catch
Response.Write("Error processing details")
End Try



The above example will look up the user jbloggs using the credentials USERNAME and PASSWORD to connect to the server and return the username and fullname, although you can retrieve any one of the properties that are mentioned, such as result.GetDirectoryEntry.Properties("department").Value for that persons department.

ASP.NET - Double click a ListBox

Ever been frustrated by a ListBox not having an OnDoubleClick event? Do not worry, all you have to do is add this simple line to the Page_Load event:



ListBox1.Attributes.Add("ondblClick", "{document.getElementById('" + Button1.UniqueID + "').click();return false;} ")



Now when you double click an item in the listbox, it will do the actions in the Button1_OnClick event. If you wanted to process something with the selected value in the ListBox, simply use the ListBox1.SelectedValue property within the Button1_OnClick event. A similar technique can also be used for other controls.

Simple but useful!

ASP.NET - Export to PDF

First of all, sorry for the lack of updates (is anyone out there reading this?) :) I'll have to update it a bit to try and bring in visitors.

Ok, we know how to export to Excel but how can we export to PDF? Below I shall explain using the iTextSharp library http://sourceforge.net/projects/itextsharp/ to export a table to PDF. There hasn't been much documentation on this on the web, especially when it's regarding VB as a language.

The example below is for exporting a table to PDF, however the functions are there to export absolutely anything, even plain text such as a word document. Make your own application and decide what you need it to do.

First of all, declare the following:


Imports iTextSharp.text
Imports iTextSharp.text.pdf
Imports System.IO

Dim ds As New System.Data.DataSet
Dim dg As New DataGrid
Dim stringWrite As New System.IO.StringWriter
Dim htmlWrite As New System.Web.UI.HtmlTextWriter(stringWrite)



Now fill your DataSet (ds) with data somehow (I used MySQL to run a query against a database) then do the following:


dg.DataSource = ds.Tables(0)
dg.DataBind()

Dim mytable As New PdfPTable(ds.Tables(0).Columns.Count)

mytable.SpacingBefore = 8
mytable.DefaultCell.Padding = 1
mytable.WidthPercentage = 100
mytable.DefaultCell.HorizontalAlignment = Element.ALIGN_JUSTIFIED
mytable.DefaultCell.VerticalAlignment = Element.ALIGN_MIDDLE

Dim t
For t = 0 To ds.Tables(0).Columns.Count - 1

Dim cell As New PdfPCell
cell.BorderWidth = 0.001F
cell.BackgroundColor = New Color(101, 197, 250)
cell.BorderColor = New Color(0, 0, 0)
cell.Phrase = New Phrase(ds.Tables(0).Columns(t).ToString, FontFactory.GetFont("TIMES_ROMAN", BaseFont.WINANSI, 8, Font.BOLD))
mytable.AddCell(cell)

Next



Dim r
Dim c

For r = 0 To ds.Tables(0).Rows.Count - 1
For c = 0 To ds.Tables(0).Columns.Count - 1

Dim cell As New PdfPCell

cell.BorderWidth = 0.001F
cell.BackgroundColor = New Color(255, 255, 255)
cell.BorderColor = New Color(0, 0, 0)
cell.Phrase = New Phrase(ds.Tables(0).Rows(r).Item(c).ToString, FontFactory.GetFont("TIMES_ROMAN", BaseFont.WINANSI, 8, Font.BOLD))
mytable.AddCell(cell)

Next
Next



First we create the columns with different formatting and then we step through every cell and build the PDF. Finally, we write the file and certain attributes:




Try

Dim mystream As New MemoryStream()
Dim document As New Document(PageSize.A4.Rotate(), 15, 15, 15, 15)
Dim writer As PdfWriter
writer = PdfWriter.GetInstance(document, mystream)
writer.SetEncryption(PdfWriter.STRENGTH40BITS, "", "", PdfWriter.AllowPrinting)
document.AddAuthor("Joe Bloggs")
document.AddSubject("Published from my ASP.NET page")
document.AddTitle("Exported Document")
document.Open()
document.Add(mytable)
document.Close()
mystream.Flush()
mystream.Close()

Dim bytearray As Byte() = mystream.ToArray
Response.Clear()
Response.AddHeader("Content-Disposition", "attachment; filename=export.pdf")
Response.ContentType = "application/pdf"
Response.BinaryWrite(bytearray)

Catch ex As DocumentException
Response.Write(ex.Message.ToString)
End Try



And there you have it! It is much easier to explain how to export normal text and not a table but if you understand how this works, the rest is easy!

A point to note is that you can allow unrestricted access to this PDF by commenting out this line: writer.SetEncryption(PdfWriter.STRENGTH40BITS, "", "", PdfWriter.AllowPrinting). This blocks editing of the document etc.

If you have any questions or problems, post a comment.