Prepoulate a form with data from a DataTable in .net

June 3, 2009 05:42 by bjones

Abstract

A simple .net class that will prepopulate form data on a page.  My requirements were to be able to find a control anywhere on a page (with or without a masterpage) and still be able to control the look of the form.  I did not want to dynamically create the controls because I want to easily control the look of the form without adding any metadata in to the database.

 

Meat and Potatoes

Inevitably when building a website I will have a page (or multiple) that should display information about an item, account, person, etc.  For example, I always have a "My Account" page where I will show the user data we have collected that could be everything from their name and email address to their shoe or ring size.  There could be a dozen or more fields displayed.  Some fields may be read-only (Label) and some may be editable (TextBox).  I start out building the page in the designer with a table and then adding all of my fields as either a TextBox or Label.  Then, I switch to the code behind and poulate a DataTable with the information I need.  The DataTable is always a single row with all that person's data.  I then have to type all the fields names and set their Text value to the DataTable's records.  Rinse and repeat, ice the wrist, rinse and repeat, etc.

In the .aspx page I may have:

[code:c#]

<table border="0" cellpadding="10" cellspacing="0">
    <tr>
        <td align="left">First Name</td>
        <td align="left"><asp:Label ID="aFName" runat="server" /></td>
    </tr>
    <tr>
        <td align="left">Last Name</td>
        <td align="left"><asp:Label ID="aLName" runat="server" /></td>
    </tr>
    .
    .
    .
</table>

[/code]

In the code behind I would then have to do this:

[code:c#]

aFName.Text = dt.Rows[0]["aFName"].ToString();
aLName.Text = dt.Rows[0]["aLName"].ToString();
aEmail.Text = dt.Rows[0]["aEmail"].ToString();
aDisplayName.Text = dt.Rows[0]["aDisplayName"].ToString();
aCellPhone.Text = dt.Rows[0]["aCellPhone"].ToString();
aSignUpDate.Text = dt.Rows[0]["aSignUpDate"].ToString();
atDesc.Text = dt.Rows[0]["atDesc"].ToString();
.
.
.

[/code]

 

This is an inefficient use of time and caffeine.  Since I do this all the time, I decided to write a class that does this in a more efficient way.  When you create the page design you have to name the controls the exact same name (case sensitive) as the column in your DataTable.  We loop through the DataTable and do a FindControl to then populate the data.  This worked fine until I created a page with a MasterPage - ugh!  FindControl isn't recursive so I hunted online and found a recursive FindControl and included it in my class.  Now it works on all pages.  I have cut my time (not caffeine intake) down considerably.  Now I can use that found time to blog :)

 

Here's the class (webhelper.cs):

[code:c#]

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

/// <summary>
/// Form functions
/// </summary>
public class webhelper
{
    /// <summary>
    /// Finds a control recursively.  Works in a page that has a masterpage, otherwise FindControl will return a null.
    /// </summary>
    /// <param name="root">Parent to search for - use "this"</param>
    /// <param name="id">Name of control you are searching for</param>
    /// <returns>Control - control you are searching for or a null if it's not found</returns>
    public static Control FindControlRecursive(Control root, string id)
    {
        if (root.ID == id)
        {
            return root;
        }

        foreach (Control c in root.Controls)
        {
            Control t = FindControlRecursive(c, id);
            if (t != null)
            {
                return t;
            }
        }

        return null;
    }

    /// <summary>
    /// Will pre-populate textbox and labels on a page with information from the first row of the DataTable. 
    /// Common use would be an account information page where you only have one row returned.
    /// TextBox and Label ID's must match the column name in the DataTable.
    /// </summary>
    /// <param name="root">Send "this" as the page root.</param>
    /// <param name="dt">DataTable with a single row.  If there are multiple rows it will only prepopulate the form with the first row.</param>
    public static void populateForm(Control root, DataTable dt)
    {
        for (int i = 0; i < dt.Columns.Count; i++)
        {
            Control c = FindControlRecursive(root, dt.Columns[i].ToString());
            if (c != null)
            {
                if (c.GetType() == typeof(TextBox))
                {
                    TextBox myBox = (TextBox)c;
                    myBox.Text = dt.Rows[0][i].ToString();
                }
                else if (c.GetType() == typeof(Label))
                {
                    Label myLabel = (Label)c;
                    myLabel.Text = dt.Rows[0][i].ToString();
                }
            }
        }


    }
}
[/code]

 

And here is how you use it on a page (dt has been defined as a DataTable and is populated with account information):

[code:c#]

webhelper.populateForm(this, dt);

[/code]

 

Wow, what an improvement in typing, huh?  In a future blog I'll show you how to do the same thing for saving the page.

You can download the class here.

 


Currently rated 1.0 by 1 people

  • Currently 1/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: Code Monkey | .net
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Sending email through GMail (or Google apps) with C#

May 29, 2009 05:18 by bjones

I have a couple of websites I've built that use GoDaddy hosting.  Instead of paying GoDaddy for their email service for my domains, I use Google Apps. It's free, they keep increasing the amount of storage (7GBs as of this blog) and I like the search feature.  In addition, I don't want to have my emails bounce as SPAM because I'm relaying it off GoDaddy's open relay so I'm bouncing it off of smtp.google.com.  Don't forget to add an SPF record (maybe I'll make that part 2 of this article).

I've been using System.Net.Mail to bounce email off a local SMTP host but had to go back to System.Web.Mail in order to authenticate for Google (my tin foil hat personality would suggest that Microsoft deprecated System.Web.Mail and left out authentication on System.Net.Mail to stop us from using Gmail). 

Below is a function I use to send email through GMail in my C# web apps.  The original code was written by Alex Sanchez for bouncing it off your local (or remote) mail server without authentication; I bastardized it to add authentication.


I have a typo in the Param section for the inFrom.  I couldn't figure out how to excape a < or > so I had to leave them out.  Make sure you use this format for your inFrom: "Name To Display" <email@domain.com>.  

Here you go: 

[code:c#]

/// <summary>
/// Sends email using Gmail or Email for Google apps.
/// </summary>
/// <param name="inFrom">From email addresses - format is: "Name To Display" email@domain.com </param>
/// <param name="inTo">To email addresses</param>
/// <param name="inSubject">Subject line</param>
/// <param name="inBody">Body of email in html markup or plain text</param>
/// <param name="inAttachmentPaths">String array of attachment paths on webserver</param>
/// <param name="isHTMLFormat">1 = HTML Format, 2 = plain text</param>
/// <param name="gmailAccountName">Account name for Gmail.  If you are using Email for Google Apps, you need to supply full email: email@domain.com</param>
/// <param name="gmailPassword">Password for your gmail account</param>
public static void SendEmailViaGmail(string inFrom, string inTo, string inSubject, string inBody, string[] inAttachmentPaths, Boolean isHTMLFormat, string gmailAccountName, string gmailPassword)
{
    System.Web.Mail.MailMessage myMailMessage = null;
   
    // Build email message
    myMailMessage = new System.Web.Mail.MailMessage();
    myMailMessage.From = inFrom;  // Format is: "Name To Display" <email@domain.com>
    myMailMessage.To = inTo;
    myMailMessage.Subject = inSubject;
    myMailMessage.Body = inBody; 
   
    if (isHTMLFormat)  // I send in plain text for SMS messages, HTML for the rest of the world
    {
        myMailMessage.BodyFormat = MailFormat.Html;
    }
    else
    {
        myMailMessage.BodyFormat = MailFormat.Text;
    }
   
   
    // Add attachments
    if (inAttachmentPaths != null)
        for (int i = 0; i < inAttachmentPaths.Length; i++)
            myMailMessage.Attachments.Add(new Attachment(inAttachmentPaths[i]));
   
   
    //  Authenticate
    myMailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate", 1);
    // Username for gmail - email@domain.com for email for Google Apps
    myMailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendusername", gmailAccountName);
    // Password for gmail account
    myMailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendpassword", gmailPassword);
    // Google says to use 465 or 587.  I don't get an answer on 587 and 465 works - YMMV
    myMailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpserverport", "465");
    // STARTTLS
    myMailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpusessl", true);
   
   
   
   
    // assign outgoing gmail server
    SmtpMail.SmtpServer = "smtp.gmail.com";
    SmtpMail.Send(myMailMessage);
}

[/code]


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: Code Monkey | SysAdmin | .net
Actions: E-mail | Permalink | Comments (1) | Comment RSSRSS comment feed

JE CAAT Scripts - Ernst and Young (Solomon)

September 29, 2008 05:26 by bjones

Earlier today (5 minutes ago?) I blogged about Oracle Financials JE CAAT and gave away the necessary scripts to build the files.  Now I'm going to do the same for Solomon. 

As stated in the Oracle blog - these scripts work for us.  I offer no guarantees or warranties of any kind.

Don't forget to replace the year and the company id below.More...

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: Code Monkey | SysAdmin
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

JE CAAT Scripts - Ernst and Young (Oracle Financials)

September 29, 2008 05:04 by bjones

It's that time of the year again, SOX audits.  There is nothing more I dread than audits; they suck all the fun out of work.  Our audit team is Ernest and Young.  A few years ago they started to require us to give them a listing of all journal entries and monthly trial balances for the year.  They take the beginning balance, roll it forward through the JE dump and make sure it matches the ending balance.  They also use it to look for any abnormalities in the numbers.  Obviously this is good for everyone expect for the poor IT guys that have to figure it out.

Get the Oracle scripts after the jump.More...

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: SysAdmin | Code Monkey
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

SQL Stored Procedure with Dynamic Where

September 26, 2008 11:26 by bjones

I'm working on a website that will be unveiled in the next few weeks.  Yearly revenue will probably bring in something between bupkis and zilch; not quite Google's numbers yet.  The site is written in C# with MS SQL 2005 on the backend.  I'm trying to conserve the limited bits and bytes in the universe and wanted to make my code as reusable as possible. 

For the sake of an example, we'll say this site allows person A to send something to person B.  Person A should be able to log in to the site and see everything they sent to A.  They should also be able to see everything someone else (person C) has sent to them.  The same query is used but the where clause is different.  I don't want to type the stored procedure twice, and I certainly don't want to maintain it twice so I went searching for a dynamic where statement within a stored procedure and I present to you my geeky friends the answer: COALESCE

Find out how to do this after the break....More...

Currently rated 1.5 by 2 people

  • Currently 1.5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: SysAdmin | Code Monkey
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Fast File Copy - Linux!

January 25, 2008 07:49 by bjones

 

All good ideas come out of necessity.  We were cloning an instance of Oracle Financials from one server to another.  There are a LOT of files under < 1k and the copy takes forever.  Yesterday the copy was kicked off using SCP - there was 39GBs to copy over a gigabit switch.  This should have been less than 10 minutes but actually took over 8 hours because of all the small files.  The copy failed and we needed to fix the problem and copy it a lot faster (30 minutes) today.

 

 After clearing up 10 GBs of log files, we were left with hundreds of thousands of small files that were going to slow us down.  We couldn't tarball the file because of a lack of space on the source server.  I started searching around and found this nifty tip that takes our encryption and streams all the files as one large file:

This requires netcat on both servers.

Destination box: nc -l -p 2342 | tar -C /target/dir -xzf -
Source box: tar -cz /source/dir | nc Target_Box 2342

It's been about 4 minutes and I'm already 1/3 of the way done!


Currently rated 3.1 by 33 people

  • Currently 3.121212/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: Code Monkey | SysAdmin
Actions: E-mail | Permalink | Comments (7) | Comment RSSRSS comment feed