Click here to Skip to main content
15,881,709 members
Articles / Web Development / ASP.NET

Fast Postback and Model Binding

Rate me:
Please Sign up or sign in to vote.
4.86/5 (28 votes)
27 Apr 2014CPOL6 min read 37.1K   989   37  
Faster way to save data on postback and simplified model binding with ASP.NET controls
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace FastPostback.Models
{
    public class ModelBinder
    {
        public static void BindControls<T>(Control control, T entity) where T : class
        {
            var properties = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public);

            foreach (PropertyInfo prop in properties)
            {
                Control ctrl = control.FindControl(prop.Name);
                if (ctrl == null)
                    continue;
                string s = ctrl.GetType().ToString();
                switch (ctrl.GetType().ToString())
                {
                    case "System.Web.UI.WebControls.TextBox":
                        ((TextBox)ctrl).Text = GetData(entity, prop.Name);
                        break;
                    case "System.Web.UI.WebControls.DropDownList":
                        ((DropDownList)ctrl).SelectedValue = GetData(entity, prop.Name);
                        break;
                    case "System.Web.UI.WebControls.HiddenField":
                        ((HiddenField)ctrl).Value = GetData(entity, prop.Name);
                        break;
                }
            }
        }

        public static T Bind<T>()
        {
            NameValueCollection formData = PrepareData(HttpContext.Current.Request.Form);
            var properties = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public);
            var instance = (T)Activator.CreateInstance(typeof(T));

            BindEntity(instance, properties, formData);
            return instance;
        }

        public static void BindEntity(object obj)
        {
            if (obj == null)
                return;

            NameValueCollection formData = PrepareData(HttpContext.Current.Request.Form);

            var properties = obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
            var instance = obj;
            var instanceType = instance.GetType();
            //var raiseError = RaiseError(instanceType);

            BindEntity(obj, properties, formData);
        }

        private static void BindEntity(object obj, IEnumerable<PropertyInfo> props, NameValueCollection data)
        {
            foreach (PropertyInfo prop in props)
            {
                if (!string.IsNullOrEmpty(data[prop.Name]))
                    SetValue(obj, prop.Name, data[prop.Name]);
            }
        }
        public static void SetValue(object inputObject, string propertyName, object propertyVal)
        {
            //find out the type
            Type type = inputObject.GetType();

            //get the property information based on the type
            System.Reflection.PropertyInfo propertyInfo = type.GetProperty(propertyName);

            //find the property type
            Type propertyType = propertyInfo.PropertyType;

            //Convert.ChangeType does not handle conversion to nullable types
            //if the property type is nullable, we need to get the underlying type of the property
            var targetType = IsNullableType(propertyInfo.PropertyType) ? Nullable.GetUnderlyingType(propertyInfo.PropertyType) : propertyInfo.PropertyType;

            //Returns an System.Object with the specified System.Type and whose value is
            //equivalent to the specified object.
            propertyVal = Convert.ChangeType(propertyVal, targetType);

            //Set the value of the property
            propertyInfo.SetValue(inputObject, propertyVal, null);

        }
        private static bool IsNullableType(Type type)
        {
            return type.IsGenericType && type.GetGenericTypeDefinition().Equals(typeof(Nullable<>));
        }

        private static string GetData<T>(T item, string col) where T : class
        {
            return Convert.ToString(item.GetType().GetProperty(col).GetValue(item, null));
        }

        private static NameValueCollection PrepareData(NameValueCollection data)
        {
            NameValueCollection list = new NameValueCollection();

            foreach (string key in data.AllKeys)
            {
                string newKey = key.Substring(key.LastIndexOf('$') + 1);
                list.Add(newKey, data[key]);
            }

            return list;
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
India India
Anurag Gandhi is a Freelance Developer and Consultant, Architect, Blogger, Speaker, and Ex Microsoft Employee. He is passionate about programming.
He is extensively involved in Asp.Net Core, MVC/Web API, Node/Express, Microsoft Azure/Cloud, web application hosting/architecture, Angular, AngularJs, design, and development. His languages of choice are C#, Node/Express, JavaScript, Asp .NET MVC, Asp, C, C++. He is familiar with many other programming languages as well. He mostly works with MS SQL Server as the preferred database and has worked with Redis, MySQL, Oracle, MS Access, etc. also.
He is active in programming communities and loves to share the knowledge with others whenever he gets the time for it.
He is also a passionate chess player.
Linked in Profile: https://in.linkedin.com/in/anuraggandhi
He can be contacted at soft.gandhi@gmail.com

Comments and Discussions