Find First Day of Month, Last Day of Month, etc

Today I was writing some code where I needed to calculate the end of the month for a certain date.  As per usual, I Googled, and found various examples, some using old VB functions, some using methods of the Date object,  some very involved and using lots of string manipulation and converting of things from dates to strings and back again, etc.  I used these various examples to develop a little utility class, which is as follows:

Public Class UtilityDates

Public Shared Function GetFirstOfMonth() As Date
Return GetFirstOfMonth(DateTime.Today)
End Function

Public Shared Function GetFirstOfNextMonth() As Date
Return GetFirstOfNextMonth(DateTime.Today)
End Function

Public Shared Function GetEndOfMonth() As Date
Return GetEndOfMonth(DateTime.Today)
End Function

Public Shared Function GetEndOfLastMonth() As Date
Return GetEndOfLastMonth(DateTime.Today)
End Function

Public Shared Function GetFirstOfMonth(ByVal startDate As Date) As Date
‘remove all but one day from date to get first of month
Return startDate.AddDays(-(startDate.Day – 1))
End Function

Public Shared Function GetFirstOfNextMonth(ByVal startDate As Date) As Date
‘get first of month and then add one month
Return GetFirstOfMonth(startDate).AddMonths(1)
End Function

Public Shared Function GetEndOfMonth(ByVal startDate As Date) As Date
‘subtract one day from first of last month
Return GetFirstOfNextMonth(startDate).AddDays(-1)
End Function

Public Shared Function GetEndOfLastMonth(ByVal startDate As Date) As Date
‘subtract one day from first of the month
Return GetFirstOfMonth(startDate).AddDays(-1)
End Function

End Class

Note that each method is overloaded, so you can calculate from the default of today’s date, or send in a specific date.  Of course, you could add a few more functions from here, but I thought that this was plenty for today:)

Get Max Number from Datatable using the Compute method

This is a nifty little thing I came across recently.  I wanted to get the maximum value of a number field from a datatable, and learned about the Datatable’s Compute method.  It’s really easy to use.  The method takes two arguments – an expression argument, which is the aggregate expression you want to use (Count, Max, Sum, etc), and a filter expression, which functions like a SQL WHERE clause.  If you don’t want to filter by anything, you can send Nothing for the second argument (Null in C#).

An example:

Dim expression As String
Dim filter as string
Dim maxNum As Integer

‘get maximum job number from table
expression = “Max(JobNumber)”
filter = “JobDate > 12/31/06 AND JobDate < 1/1/08”
maxNum = CInt(tblJobInfo.Compute(expression, filter))

If you don’t want to filter, it would look like this:

expression = “Max(JobNumber)”
maxNum = CInt(tblJobInfo.Compute(expression, Nothing))

Use Generic Methods to create a Session Wrapper class

Getting values out of session in ASP.NET can be a bit of a pain for two reasons:

  1. You have to remember what you named the value when you put it in
  2. You have to type cast the value, as session stores it in an Object

One nice way to handle this is to build a wrapper class to handle getting values into and out of session. And an even nicer way is to use generic methods in your wrapper class.

Here’s how I implement this in my projects. First, I have a class called SessionBase that contains two shared Generic methods, LoadValue and RetrieveValue:

Public Class SessionBase

Public Shared Function RetrieveValue(Of T)(ByVal keyName As String) As T

If HttpContext.Current.Session(keyName) IsNot Nothing Then
Return DirectCast(HttpContext.Current.Session(keyName), T)
End If

End Function

Public Shared Sub LoadValue(Of T)(ByVal keyName As String, ByVal value As T)

HttpContext.Current.Session(keyName) = value

End Sub

End Class

The beauty of these methods is that they can handle any data type – I don’t have to have separate methods for integers, collections, custom types, etc. It’s all handled here in this generic and reusable class (I usually keep it in a .dll along with other base classes, and add a reference to it in my project). I use DirectCast rather than CType in my retrieve method because it is supposed to have less of a performance penalty.

Then, in my project, I create a class called sess that inherits the base class (because the base class contains shared methods, it doesn’t really need to be inherited, but I prefer to do it this way so there is less typing – I can type sess.LoadValue instead of TKS.SessionBase.LoadValue). In the project-specific class, I create constants for the session key names, and shared properties to load and retrieve values from session:

Public Class sess
Inherits TKS.Web.SessionBase

Private Const cProjID As String = "ProjID"
Private Const cProjName As String = "ProjName"

Public Shared Property ProjID() As Integer
Get
Return sess.RetrieveValue(Of Integer)(cProjID)
End Get
Set(ByVal value As Integer)
sess.LoadValue(of Integer)(cProjID, value)
End Set
End Property

Public Shared Property ProjName() As String
Get
Return sess.RetrieveValue(Of String)(cProjName)
End Get
Set(ByVal value As String)
sess.LoadValue(Of String)(cProjName, value)
End Set
End Property

End Class

Note how the generic methods are made specific at this point – Integer for ProjID, String for ProjName.

Now in my project, I can use the sess properties to easily access the session object:

Protected Sub btnLoad_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnLoad.Click

sess.ProjID = Integer.Parse(Me.txtProjectID.Text)
sess.ProjName = Me.txtProjectName.Text

End Sub

Protected Sub btnRetrieve_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnRetrieve.Click

Me.txtProjectID.Text = sess.ProjID.ToString
Me.txtProjectName.Text = sess.ProjName

End Sub

Determine Previous WizardStep using Wizard’s GetHistory Method

Recently I was working on a project that contained an ASP.NET Wizard Control. The control was configured to allow non-linear progression through the WizardSteps. I realized that I needed to know which step the user had been on previously, as that would determine which control would have focus in the current step.

So I Googled, and was able to find out that I could use the Wizard Control’s GetHistory method to find the previous step. GetHistory returns a collection of the WizardStepBase objects that have been accessed, arranged in the order that they were accessed – the first object in the collection is the WizardStep that was accessed last, the next is the WizardStep that was accessed second-to-last, etc.

OK, so far, so good. But the MSDN documentation didn’t include an example of how to use the GetHistory method, and neither did the couple other mentions I found in other articles – they all said you could do it, but they didn’t say how.

So I played around, and figured out a way to use the GetHistory method to get what I needed. Anyone who knows of a smoother or more elegant way, please feel free to post it – I just thought there should be at least one example out there:-)

Example:

Dim steps As ArrayList
Dim stp As WizardStep

'get WizardSteps history collection
steps = CType(Me.wzDataEntry.GetHistory, ArrayList)

'if any wizard steps have been previously accessed...
If steps.Count > 0 Then

'get last wizard step
stp = CType(steps.Item(0), WizardStep)

'if last step was 'Project Info', set focus on region dropdownlist
If stp.ID = "stpProjectInfo" Then
Me.ddlRegion.Focus()
End If

End If

Recursive method to reset controls in a ControlCollection

This is a shared public method used to recursively interate through the controls in a control collection and set specified controls to an empty or unselected state.

First, I build two private shared helper methods to deal with an individual control. The first one checks to see what kind of control it is:

‘Helper function to check for type of control in a collection
Private Shared Function CheckControlType(ByVal ctl As Control) As Boolean

If TypeOf (ctl) Is TextBox Or TypeOf (ctl) Is DropDownList Or _
TypeOf (ctl) Is CheckBox Or TypeOf (ctl) Is RadioButton Or _
TypeOf (ctl) Is ListBox Or _
(TypeOf (ctl) Is Label And ctl.ID.StartsWith("lbl")) Then

Return True

End If
End Function

You’ll notice that for a label control I also test to see if the label’s ID starts with the characters ‘lbl’. This is because the ASP.NET Validation Controls are treated as Labels when looping through the collection, and I don’t want to evaluate those. So I make sure I name labels I want to check lblSomething so I can specify that only those will be checked.

The second helper method resets the control:

‘Helper function to reset fields
Private Shared Sub ResetFields(ByVal ctl As Control)

If TypeOf (ctl) Is TextBox Then
CType(ctl, TextBox).Text = “”
ElseIf TypeOf (ctl) Is Label Then
CType(ctl, Label).Text = “”
ElseIf TypeOf (ctl) Is DropDownList Then
CType(ctl, DropDownList).SelectedValue = “-1”
ElseIf TypeOf (ctl) Is CheckBox Then
CType(ctl, CheckBox).Checked = False
ElseIf TypeOf (ctl) Is RadioButton Then
CType(ctl, RadioButton).Checked = False
ElseIf TypeOf (ctl) Is ListBox Then
CType(ctl, ListBox).SelectedValue = “”
End If

End Sub

Once these helpers are in place, I recursively loop through the control collection and call the helpers as needed.

‘Clear fields in a collection
Public Shared Sub ClearFields(ByVal Controls As ControlCollection)

‘Iterate through control collection – if type of control is textbox,
‘dropdownlist, checkbox, radiobutton, label or listbox, clear control
For Each ctl As Control In Controls

‘clear main controls in collection
If CheckControlType(ctl) Then
ResetFields(ctl)

‘Recursion – if control has its own control collection (e.g., panel, div, etc)
‘method calls itself to clear that collection
ElseIf ctl.HasControls Then
ClearFields(ctl.Controls)

End If
Next

End Sub

I keep this method in a class called Presentation, which contains a variety of utility methods having to do with formatting and configuring pages and controls. I can then call this public shared method from anywhere in my code, passing it whatever ControlCollection I want it to process:

Presentation.ClearFields(divEdit.Controls)

Using System.Net.Mail namespace to send email

Here’s a little demo of how to use the System.Net.Mail namespace to have your application automatically send an email. This sample is a class method that sends an email notification to the developer/webmaster/website owner/whoever when a new user registers on the site.

First, some set up. I keep the values for the From email address and the host IP address in the appSettings section of the web.config file. To retrieve them, I have a couple shared ReadOnly properties in my class, like so:

Public Shared ReadOnly Property Host() As String
Get
Return System.Configuration.ConfigurationManager.AppSettings("Host").ToString
End Get
End Property

Public Shared ReadOnly Property FromAddress() As String
Get
Return System.Configuration.ConfigurationManager.AppSettings("From").ToString
End Get
End Property

Now that I can easily get to these settings, I build my method, as below:

”’ <summary>
”’ Send email notification when a new user registers
”’ </summary>
”’ <param name=”ToAddress”>System.String containing the email
”’ address that the message should go to
”’ </param>
Public Shared Sub NotifyEmail(ByVal ToAddress As String)

Try

‘instantiate new MailMessage object and pass in from and to
’email addresses (FromAddress is a readonly property pulling from
‘web.config file)
Using message As New System.Net.Mail.MailMessage(FromAddress, ToAddress)

‘set rest of message properties
message.Subject = "New User"
message.IsBodyHtml = True
‘set to true if you want to use html in body
message.Body = "A new user has registered"

‘instantiate new SmtpClient object and pass in host information
‘(Host is a readonly property pulling from web.config file)
Dim smtp As New System.Net.Mail.SmtpClient(Host)

‘send message
smtp.Send(message)

‘dispose of MailMessage object
End Using

Finally

‘dispose of SmtpClient object
smtp = Nothing

End Try

End Sub