[程式開發技巧] 在ASP.NET WebForm將POST資料自動轉換為物件 | 物件關係對映

通常MVC與WebAPI都有內建POST資料轉換功能
但是WebForm沒有內建這個功能
(尤其是跨頁POST時處理就會比較麻煩)

本程式碼主要用於呼叫一次方法
就可以自動將Form的資料轉換為物件
相較於KeyValue
物件存取會容易閱讀與維護

::引用命名空間::

using System.Reflection;
using System.Collections.Specialized;
using System.ComponentModel.DataAnnotations.Schema;

::方法實作:: (放置於已繼承UI.Page的程式碼中)

protected T GetPost<T>()
{
    //利用泛型建立物件
    T result = (T)Activator.CreateInstance(typeof(T));
    Mapping(result, Request.Form);
    return result;
}

private void Mapping(object obj, NameValueCollection collection)
{
    PropertyInfo[] properties = obj.GetType().GetProperties();
    foreach (PropertyInfo prop in properties)
    {
        //取得Attribute Name,如果沒有就取Property Name
        ColumnAttribute attribute = (ColumnAttribute)prop.GetCustomAttribute(typeof(ColumnAttribute));
        string name = attribute != null ? attribute.Name : prop.Name;
        string value = collection[name].ToString();
        //型別判斷與資料轉換
        if (prop.PropertyType == typeof(int) ||
            //Enum判斷 + Enum的基礎型別判斷
            (prop.PropertyType.IsEnum && prop.PropertyType.GetEnumUnderlyingType() == typeof(int)))
        {
            int result = default;
            int.TryParse(value, out result);
            prop.SetValue(obj, result);
        }
        else if (prop.PropertyType == typeof(float))
        {
            float result = default;
            float.TryParse(value, out result);
            prop.SetValue(obj, result);
        }
        else if (prop.PropertyType == typeof(DateTime))
        {
            DateTime result = default;
            DateTime.TryParse(value, out result);
            prop.SetValue(obj, result);
        }
        else if (prop.PropertyType == typeof(string))
        {
            prop.SetValue(obj, value);
        }
        //型別判斷與資料轉換(Nullable型別)
        else if (prop.PropertyType == typeof(int?))
        {
            int? result = null;
            if (int.TryParse(value, out int origin))
            {
                result = origin;
            }
            prop.SetValue(obj, result);
        }
        else if (prop.PropertyType == typeof(float?))
        {
            float? result = null;
            if (float.TryParse(value, out float origin))
            {
                result = origin;
            }
            prop.SetValue(obj, result);
        }
        else if (prop.PropertyType == typeof(DateTime?))
        {
            DateTime? result = null;
            if (DateTime.TryParse(value, out DateTime origin))
            {
                result = origin;
            }
            prop.SetValue(obj, result);
        }
    }
}

::Model類別::

public class IndexModel
{
    [Column("tboxName")]
    public string Name { get; set; }

    [Column("tboxAge")]
    public int Age { get; set; }

    [Column("tboxBirthday")]
    public DateTime? Birthday { get; set; }

    [Column("lboxGender")]
    public Gender Gender { get; set; }
}

::呼叫範例::

IndexModel model = GetPost<IndexModel>();

**範例中的程式碼可以依照需求進行增減**

Github專案連結

留言