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


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 JetBrains TeamCity

    clock March 9, 2008 16:34 by author csmith12

    A friend and I have been working with TeamCity from JetBrains for the past week. I must say that I am impressed with the application so far. I do have a couple of issues I am still working out, but all and all, its a killer continuous integration server for free. Here are just a few of the questions that I have not been able to figure out from reading the documentation so far;

    1. How do I get the build agents to build applications that contain 3rd party project references without installing them on the build server or where the build agent is installed? Am I missing something that is taken for granted here?
    2. Is there any plug-ins/add-on's that will deploy the compiled output (artifacts) to a staging server automatically?

    If any experienced TeamCity users read this, please point me in the right direction.

    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


    Forgotten or underused SQL column expressions

    clock November 24, 2007 02:24 by author csmith12
    MicroSoft SQL Server column expressions can simplify some of the logic in your database schema or application logic by allowing expressions to derive the value of a database table column.

    For example;

    I was needing to perform some basic calculations for order line items. Rather than creating a trigger to multiple the QTY ordered by the selling PRICE of the item and place that value in the TOTAL column, I used an expression in the TOTAL column to do this multiplication for me. Here is a screenshot.


     
    After this setup on the column, you will find that all records will have the proper order total automatically. No need to code triggers, put in application logic to calculate and update the value.

    In real world usage I am sure it will not be this simple. You will want to make careful choices about what belongs in the column spec. or in the business rule logic.

    Best of luck.

    Be the first to rate this post

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


    Infragistics Grid Updating

    clock November 24, 2007 02:06 by author csmith12

    I sometimes use the Infragistics control suite. In specifically, I will utilize their grid control in my projects. This is one of the best grids out there, but it has some gotchas. One of the issues that commonly arise with this control deals with committing data to the DataSource (database, XML, etc...).

    Example:

    1. I drop a grid on a windows forms UserControl
    2. In the load event of the UserControl I bind my data
    3. I drag the UserControl on to a form
    4. I update the properties to allow user to edit data in the grid per requirements

    Now the issue with this is, when the user selects the 'X' on the main form the controls on the form will start to dispose. So none of the databinding events fire on the grid to update the DataSource that the grid is bound to. So, if you call Update(); on your table adapter. The RowState of the rows have not been changed and nothing will persist to the database.

    Fix:

    1. Develop your UserControl as normal or as basically described above
    2. Expose the grid as a public object on your UserControl
    3. On the containing form's closing event call the grid's UpdateData() method to force all user changes to the DataSource of the grid control
    4. Call update on the table adapters or whatever persisting method you utilize to save data to your persistent store.

    Hope this helps someone out.

    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