Cleaning up Web Form Binding to Entity Objects

clock October 26, 2008 05:27 by author csmith12

How many lines of code have we all written to set properties from a web form to a business object. 1000's of lines of code and countless wasted hours developing and debugging typos in field names. After years it gets old.

I found a article (http://msdn.microsoft.com/en-us/library/aa478957.aspx) on Microsoft's site about doing just what my goal was. My goal was to turn the hundreds of lines of code in application setting UI properties into business object properties.

For example;

Normal code;

// create entity
Person p = new Person(1, "John", "Doe");

p.FirstName = FirstName.Text;
p.LastName = LastName.Text;

// more code...
Goal code;

// create entity
Person p = new Person(1, "John", "Doe");

// bind
Binder.BindToControl(p, Page);

Enter the Binder class that I have so far after about 2 hours of R&D and playing around with different setups.

using System;
using System.Reflection;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Pixelect.Example.Web
{
    public static class Binder
    {
        public static void BindToControl(object entity, Control control)
        {
            // ensure objects
            if (entity == null || control == null) return;

            // get properties
            PropertyInfo[] infos = entity.GetType().GetProperties();

            // loop through each property info object
            foreach (PropertyInfo info in infos)
            {
                // if can read property
                if (info.CanRead)
                {
                    // find matching control
                    Control matchingControl = control.FindControl(info.Name);

                    // check for match
                    if (matchingControl == null) continue;

                    // process type
                    if (matchingControl is TextBox)
                        ((TextBox) matchingControl).Text = Convert.ChangeType(info.GetValue(entity, null), typeof(string)).ToString();

                    if (matchingControl is Literal)
                        ((Literal)matchingControl).Text = Convert.ChangeType(info.GetValue(entity, null), typeof(string)).ToString();

                    if (matchingControl is Label)
                        ((Label)matchingControl).Text = Convert.ChangeType(info.GetValue(entity, null), typeof(string)).ToString();

                    if (matchingControl is ListControl)
                    {
                        ListItem li = ((ListControl)matchingControl).Items.FindByValue(info.GetValue(entity, null).ToString());
                        if (li != null)
                        {
                            foreach (ListItem item in ((ListControl)matchingControl).Items)
                                item.Selected = false;

                            li.Selected = true;
                        }
                    }
                }
            }
        }
        public static void BindToObject(Control control, object entity)
        {
            // ensure objects
            if (entity == null || control == null) return;

            // get properties
            PropertyInfo[] infos = entity.GetType().GetProperties();

            // loop through each property info object
            foreach (PropertyInfo info in infos)
            {
                // if can read property
                if (info.CanWrite)
                {
                    // find matching control
                    Control matchingControl = control.FindControl(info.Name);

                    // check for match
                    if (matchingControl == null) continue;

                    // process type
                    if (matchingControl is TextBox)
                        info.SetValue(entity, Convert.ChangeType(((TextBox)matchingControl).Text, info.PropertyType), null);

                    if (matchingControl is ListControl)
                    {
                        if (((ListControl)matchingControl).SelectedItem != null)
                            info.SetValue(entity, Convert.ChangeType(((ListControl)matchingControl).SelectedItem.Value,  info.PropertyType), null);
                    }
                }
            }
        }
    }
}

This class allows easy binding between web form UI elements and entity objects where the UI control ID is equal to the entity property name. This is just a first draft of the class and I will be updating the class to support the bulk of the toolbox items in visual studio. I will also integrate the code from the Microsoft article to support known properties on unknown UI object types.

Then hopefully.... we can cut down on all that error prone and boring code that we all must type to bind UI elements to back end objects.

Enjoy

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


.Net with SMO, Triggers, Tables and the Modified (Last Updated Date)

clock October 4, 2008 04:12 by author csmith12

Have you ever had a lot of tables in a database that needed to have the timestamp of the record updated on insert or update? I know I have. I wish I could find a really good tool for automating some of the database development tasks that I perform. Until then, I end up writing my own scripts or code.

This code utilizes the .Net SMO object model to automatically create triggers for tables that have an Modified datetime column.

Below you will see my code for adding triggers to a MS SQL server database. These triggers will update the "Modified" column in the table when a record is inserted or updated. Feel free to modify the code to fit your specific needs as it is common for the "Modified" column to be named differently per database/project.

Limits:

1. Table can only have one primary key column

Enjoy!

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.SqlClient;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;

namespace Pixelect.MsSql
{
    public class ModifiedDateTriggerGenerator
    {
        public void Process(string database)
        {
            // get connection string
            string conString = ConfigurationManager.ConnectionStrings["SqlServerConnectionString"].ConnectionString;

            // create sql connection
            SqlConnection sqlConnection = new SqlConnection(conString);

            // create server connection
            ServerConnection serverConnection = new ServerConnection(sqlConnection);

            // create server
            Server server = new Server(serverConnection);    

            // 
            if (server.Databases.Contains(database))
                AddModifiedTriggerToTables(server.Databases[database]);
            else
                throw new Exception("Database not found.");
        }

        private static void AddModifiedTriggerToTables(Database database)
        {
            foreach (Table table in database.Tables)
            {
                if(table.Columns.Contains("ModifiedDate"))
                {
                    // check if table already had trigger, drop it
                    if (table.Triggers.Contains(string.Format("trg{0}SetModifiedDate", table.Name)))
                        table.Triggers[string.Format("trg{0}SetModifiedDate", table.Name)].Drop();
                    
                    // set up trigger
                    Trigger trigger = new Trigger(table, string.Format("trg{0}SetModifiedDate", table.Name));
                    trigger.TextMode = false;
                    trigger.Insert = true;
                    trigger.Update = true;

                    // get trigger resource
                    string textBody = TriggerTemplate.ResourceManager.GetString("ModifiedDateTrigger");

                    // get template
                    if(string.IsNullOrEmpty(textBody))
                        throw new Exception("Unable to get Modified trigger template from resource.");

                    // swap values
                    textBody = textBody.Replace("[table]", string.Format("[{0}]", table.Name));
                    textBody = textBody.Replace("[schema]", string.Format("[{0}]", table.Schema));

                    // get primary key of table
                    List<Column> keys = GetPrimaryKeys(table);

                    // i.[primaryKey] = [schema].[table].[primaryKey]
                    string keyChain = string.Empty;
                    foreach (Column col in keys)
                        keyChain += string.Format("i.{0} = [{1}].[{2}].[{3}] AND ", col.Name, table.Schema, table.Name, col.Name);
                    
                    // replace body
                    keyChain = keyChain.Substring(0, keyChain.Length - 5);
                    textBody = textBody.Replace("[keys]", keyChain);
                    
                    // update body
                    trigger.TextBody = textBody;

                    // create trigger
                    trigger.Create();
                }
            }
        }

        private static List<Column> GetPrimaryKeys(Table table)
        {
            List<Column> keys = new List<Column>();

            foreach (Column c in table.Columns)
                if (c.InPrimaryKey) keys.Add(c);

            return keys;
        }
    }
}

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Adding Glass Effect to Images

clock February 28, 2008 11:27 by author csmith12

I found a very nice article on Code Project that shows a simple implementation of a glass effect applied to an image. I thought I would credit the developer and link his code here for my future reference.

        public static Image DrawReflection(Image _Image, Color _BackgroundColor, int _Reflectivity)
        {
            // Calculate the size of the new image
            int height = (int)(_Image.Height + (_Image.Height * ((float)_Reflectivity / 255)));
            Bitmap newImage = new Bitmap(_Image.Width, height, PixelFormat.Format24bppRgb);
            newImage.SetResolution(_Image.HorizontalResolution, _Image.VerticalResolution);

            using (Graphics graphics = Graphics.FromImage(newImage))
            {
                // Initialize main graphics buffer
                graphics.Clear(_BackgroundColor);
                graphics.DrawImage(_Image, new Point(0, 0));
                graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                Rectangle destinationRectangle = new Rectangle(0, _Image.Size.Height, _Image.Size.Width, _Image.Size.Height);

                // Prepare the reflected image
                int reflectionHeight = (_Image.Height * _Reflectivity) / 255;
                Image reflectedImage = new Bitmap(_Image.Width, reflectionHeight);

                // Draw just the reflection on a second graphics buffer
                using (Graphics gReflection = Graphics.FromImage(reflectedImage))
                {
                    gReflection.DrawImage(_Image, new Rectangle(0, 0, reflectedImage.Width, reflectedImage.Height),
                    0, _Image.Height - reflectedImage.Height, reflectedImage.Width, reflectedImage.Height, GraphicsUnit.Pixel);
                }
                reflectedImage.RotateFlip(RotateFlipType.RotateNoneFlipY);
                Rectangle imageRectangle = new Rectangle(destinationRectangle.X, destinationRectangle.Y,
                    destinationRectangle.Width, (destinationRectangle.Height * _Reflectivity) / 255);

                // Draw the image on the original graphics
                graphics.DrawImage(reflectedImage, imageRectangle);

                // Finish the reflection using a gradiend brush
                LinearGradientBrush brush = new LinearGradientBrush(imageRectangle,
                       Color.FromArgb(255 - _Reflectivity, _BackgroundColor),
                        _BackgroundColor, 90, false);
                graphics.FillRectangle(brush, imageRectangle);
            }

            return newImage;
        }
Link to the original article. http://www.codeproject.com/KB/GDI-plus/Image-Glass-Reflection.aspx

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Basic Thumbnail with Aspect Ratio Preservation

clock January 28, 2008 14:24 by author csmith12

While working different applications, you will need to preserve aspect ratio of images while creating a high quality thumbnail. There are plenty of examples of this on various sites, so I figure one more will not hurt.

[TestFixture]
public class ImageResizingTestFixture
{
    [Test]
    public void TestResizeImageFromMemoryStream()
    {
        Graphics g;

        // create a source bitmap image
        Bitmap source = new Bitmap(500, 500);

        g = Graphics.FromImage(source);

        // draw a background color
        g.FillRectangle(new SolidBrush(Color.Red), 0, 0, 500, 500);
        g.DrawEllipse(new Pen(Color.White), 0, 0, 50, 50);

        // call private thumb
        Bitmap thumbnail = CreateThumbnail(source, 177, 103);

        // save image as stream
        MemoryStream sourceStream = new MemoryStream();
        source.Save(sourceStream, ImageFormat.Jpeg);
        sourceStream.Position = 0;
    }

    private static Bitmap CreateThumbnail(Image source, int width, int height)
    {
        // get the new size
        Size size = GetResizeDimensions(source.Width, source.Height, width, height);

        // create thumbnail holder
        Bitmap thumb = new Bitmap(width, height);
        Graphics g = Graphics.FromImage(thumb);

        // set graphic options
        g.CompositingQuality = CompositingQuality.HighQuality;
        g.SmoothingMode = SmoothingMode.HighQuality;
        g.InterpolationMode = InterpolationMode.HighQualityBicubic;

        // draw the source onto the thumbnail

        g.DrawImage(source, 0, 0, size.Width, size.Height);

        g.Dispose();

        return thumb;
    }

    public static Size GetResizeDimensions(int currentWidth, int currentHeight, int desiredWidth, int desiredHeight)
        {
            double liChange;
            int newHeight;
            int newWidth;

            if (currentHeight == currentWidth)
            {
                // image is square...
                // we can use either height or width to resize....
                // use height
                liChange = 1.0 * desiredHeight / currentHeight;
                newHeight = (int) (currentHeight * liChange);
                newWidth = (int)(currentWidth * liChange);
            }
            else if (currentHeight < currentWidth)
            {
                // image is landscape...use width to resize
                liChange = 1.0 * desiredWidth / currentWidth;
                newHeight = (int) (currentHeight * liChange);
                newWidth = desiredWidth;
            }
            else
            {
                // image is portrait...
                liChange = 1.0 * desiredHeight/currentHeight;
                newHeight = desiredHeight;
                newWidth = (int)(currentWidth * liChange);
            }

            if (currentHeight <= desiredHeight & currentWidth <= desiredWidth)
            {
                newHeight = currentHeight;
                newWidth = currentWidth;
            }

            return new Size(newWidth, newHeight);
        }
}

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Fun with Regex

clock December 6, 2007 00:15 by author csmith12

Sometimes when coding applications, your run into problems that seem to be easy to fix but end up being very difficult to fix in a standard way. Now here was my situation.

  1. One stock web form
  2. One stock asp.net textbox control
  3. One stock asp.net regular expression validator
  4. One stock asp.net button

Problem: This textbox was for number data entry. It should accept number values such as 1, 50, 897, or 2,309. Now initial thoughts say that this should be a easy regular expression.

Solution: After a lot of trial and error I finally end up with this regular expression: -?([1-9][0-9]{0,2}(,[0-9]{3,3})*|0|[1-9]{1}[0-9]*)

And finally for the funny part of this post. I pasted my regex in a chat with my body and got this response. HAHAHAHAHAHAHAH!

reactor:     -?([1-9][0-9]{0,2}(,[0-9]{3,3})*|0|[1-9]{1}[0-9]*)  
reactor:     look at that nugget   
k00k|wrk:     lol 
k00k|wrk:     jeez 
k00k|wrk:     good work 
k00k|wrk:     you just got the combination to my luggage 
reactor:      lol 

Aren't friends great for a laugh?

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


General serialization class

clock November 25, 2007 13:49 by author csmith12

Just thought I would post this for everyone else to use, alter, review, whatever....

using System;

using System.IO;

using System.Xml;

using System.Xml.Serialization;

 

namespace Catalyst.UtilityClasses

{

  public class Serializer

  {

    public static object Deserialize(string file, Type type)

    {

      object obj;

      XmlReader reader = null;

      FileStream fs = null;

 

      try

      {

        // get a serializer to serialize the passed in object type

        XmlSerializer serializer = new XmlSerializer(type);

 

        // open the file stream

        fs = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read);

 

        // create an xml reader from the file stream

        reader = new XmlTextReader(fs);

 

        // use the Deserialize method to restore the object's state.

        obj = serializer.Deserialize(reader);

      }

      finally

      {

        // close any open streams

        if (fs != null)

          fs.Close();

 

        if (reader != null)

          reader.Close();

      }

 

      return obj;

    }

    public static void Serialize(string file, object obj)

    {

      TextWriter writer = null;

 

      try

      {

        // get a serializer to serialize the passed in object type

        XmlSerializer serializer = new XmlSerializer(obj.GetType());

 

        writer = new StreamWriter(file);

        serializer.Serialize(writer, obj);

      }

      finally

      {

        // close any open streams

        if (writer != null)

          writer.Close();

      }

    }

  }

}

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


SandDock form closing event handling.

clock November 25, 2007 13:47 by author csmith12

I have some applications that use Divelements sanddock. For a while I fussed with getting the close event on my dock controls to fire when the hosting application window was closed. After some tweaking, I have come up with some code that is acceptable.

In the main form I have this code in the close event.

      foreach (DockControl control in dockManager.GetDockControls())

        control.Close();


After putting that code in the main form, the close events on your dock controls as well as tabbed documents will fire as they should. Sometimes things are so simple, developers over think the solution.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


QOTD

Have you ever needed a Captain Crunch Decoder Keyring to figure out code before? I have.....

- Reactor

Calendar

<<  March 2010  >>
MoTuWeThFrSaSu
22232425262728
1234567
891011121314
15161718192021
22232425262728
2930311234

View posts in large calendar

Sign in