Some Silly things I have seen Base Pages for in Asp.Net

clock December 19, 2008 06:38 by author csmith12

After working in the field for a while, I have ran across some silly stuff I have seen other developers do. Below is a list. I am hoping that between my knowledge, and the experience of others. Some better approaches can be derived. Feel free to comment below to add your own silly issue.

 

Silly Issue 1: Use a base page to set page title.
Now this issue can be solved in many ways. Overall I go for the simplest approach if it will satisfy the needs. for example;

protected override void Render(HtmlTextWriter writer)
{
    Page.Title = string.Format("My site title - {0}", Page.Title);
    base.Render(writer);
}
Put that code in your master page. Or even better yet would be to pull the site title from the web.config.

Silly Issue 2: Use a base page to initialize connections to a database.
Simple.... never, never, never, never do this. When the database goes offline, there is no reason that a static page should break. Instead just utilize some data access framework, TableAdapters, Linq.... anything.

 

Silly Issue 3: Use a base page to enforce a proper URL (www.xyz.com or xyz.com).
This is also simple, fight the temptation to do this via code, and ask the IT guys to do this via DNS or some other technology. There is no reason to muddy up the code of a web site for this reason, and will come back to bite you on DEV and STG environments anyway. So even more code/configuration to support a silly decision in the first place.

 

Silly Issue 4: Use a base page to handle error handling.
Do not do this. Handle code errors in a standard way, such as per page. And for the unhandled exceptions, utilize a IHttpModule that hooks the context.Error. Such as below maybe;

public class EmailErrorHandler : IHttpModule
  {
    #region IHttpModule Members

    public void Dispose() {}

    public void Init(HttpApplication context)
    {
      // wire global error handle
      context.Error += ApplicationError;
    }

Then add the type to the web.config in the HttpModules section. Create an ApplicationError method that performs the actions you need. As you can see by the title of my class, mine sends an email.

Hopefully this will save someone some time.



Be the first to rate this post

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


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


Common User Mistake

clock September 25, 2008 02:20 by author csmith12

After developing web pages for so long, and as a web user for a long time.... Sometimes we start to overlook the simple things.

For example;
A user sent me a screen shot stating the colors were messed up on a set of textboxes on a web form. After a few minutes confirming the CSS, I looked at the screen shot again. All the text boxes had a yellow background.

The answer was also right there in front of me as well, but as complacent as I was, it didn't hit me until the 2nd look. The Google toolbar was also installed and the autofill button was lit up. Ah the answer to my question is there in the options.

The fix is to have the user turn off the yellow color highlighting as shown below.

google yellow highlight

Be the first to rate this post

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


Enabling Membership, Roles and Personalization in ASP.Net

clock April 8, 2008 16:12 by author csmith12

How to configure the ASP.NET 2.0 Membership/Roles Provider to use SQL 2000 or SQL 2005?

The information in this article applies to:

  • ASP.NET 2.0
  • MS SQL 2000
  • MS SQL 2005
  • Membership/Roles Provider

    SUMMARY

    How to set up the new ASP.NET 2.0 Membership, Role Management, and Personalization services to use a regular hosted SQL Server 2005 or SQL 2000 instead of MicroSoft SQL Server Express.

    DETAILS

    The following steps create the full Application Services database schema on our SQL Server database.

    1. Open the command prompt on your local computer, and navigate to:
      C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727
    2. Execute the command:
      aspnet_regsql.exe -S [DB Server Name] -U [DB login] -P [Password] -A all -d [Database name]

    Below is an example of how to configure Visual Web Developer to manage the membership database.

    1. Create a web application in Visual Web Developer or Visual Studio 2005.
    2. Open the web.config.
    3. The default membership provider uses a connection string called "LocalSqlServer".          

    Replace:

    <connectionStrings/>

    with

    <connectionStrings><remove name="LocalSqlServer" />
    	<add name="LocalSqlServer" connectionString="Data Source=<DB_Server>;Integrated Security=false;Initial 
    		Catalog=<DB_Name>;User ID=<DB_User>;Password=<DB_password>" providerName="System.Data.SqlClient" />
    </connectionStrings>
     Save and close the web.config. 
    1. Go to Website menu, and run the ASP.NET Configuration tool. This will open the Web Site Administration tool in a browser window.
    2. Next.. In the Web Site Administration browser, go to the Security tab.
    3. Click on "Select authentication type".
    4. Select "From the internet".  Then click the "Done" button.
    5. Create your admin roles and users.
    6. Then create access rules.
    7. Create a rule that applies to the "Anonymous users" with "Deny" permissions.
    8. Create another rule that applies to the admin role you created with "Allow" permissions.
    9. Your application is now ready to use the membership provider.
  • Copied for ease of access. Credit given to: http://support.re-invent.com/article.aspx?id=10353

    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


    QOTD

    A DBA friend of mine said... "I see a loading screen.... 5 in the clip and one in the chamber."

    - The Lonely DBA

    Calendar

    <<  January 2009  >>
    MoTuWeThFrSaSu
    2930311234
    567891011
    12131415161718
    19202122232425
    2627282930311
    2345678

    View posts in large calendar

    Sign in