处理FormCollection字段的帮助类

帮助类源码

/// <summary>
/// FormData转换帮助类
/// </summary>
public static class FormDataHelper
{
    /// <summary>
    /// 利用反射机制将formCollection中的键值对的值赋值给对象对应属性,并确保类型一致性
    /// <para>目前暂不支持form表单中含有List类型,支持到字符串数组如string[]</para>
    /// </summary>
    /// <typeparam name="T">实体泛型</typeparam>
    /// <param name="t">外部操作的全新的实体ref</param>
    /// <param name="form">form表单</param>
    /// <returns></returns>
    public static int ToModel<T>(ref T t, IFormCollection form)
    {
        int u = 0;
        var pi = t.GetType().GetProperties();
        foreach (var p in pi)
        {
            if (form.TryGetValue(p.Name, out StringValues strs))
            {
                try
                {
                    if (IsIEnumerable(p))//数组或列表或字典(本意是分别对列表list和字典分别做处理,暂时只做了数组,后续待补充)
                    {
                        if (IsArray(p))//数组判断
                        {
                            var strArr = strs.ToArray();
                            var tempArr = Activator.CreateInstance(p.PropertyType, strArr.Length) as Array;//临时创建一个数组对象,以p的数组类型创建,长度以strArr长度为准
                            for (int i = 0; i < strArr.Length; i++)
                            {
                                if (strArr[i] == "undefined") strArr[i] = null;
                                if (strArr[i] == null) continue;
                                var v = Convert.ChangeType(strArr[i], p.PropertyType.GetElementType());
                                tempArr.SetValue(v, i);
                            }
                            p.SetValue(t, tempArr, null);//反射赋值给对象的属性,同时转换类型
                            continue;
                        }
                    }
                    else//普通属性
                    {
                        if (strs.ToArray()[0] == "undefined") continue;
                        var val = Convert.ChangeType(strs.ToArray()[0], p.PropertyType);
                        p.SetValue(t, val, null);//反射赋值给对象的属性,同时转换类型
                    }
                    u++;
                }
                catch (Exception ex)
                {
                    NLogHelper.Error(ex.Message);//日志记录报错信息
                }
            }
        }
        return u;
    }
    /// <summary>
    /// 判断是否实现枚举接口 数组、字典、集合均实现了枚举接口
    /// </summary>
    /// <param name="p"></param>
    /// <returns></returns>
    private static bool IsIEnumerable(PropertyInfo p)
    {
        //List和Array均实现了枚举 IEnumerable 接口,通过判断是否实现该接口得知是否为[List或Array]
        return p.PropertyType.GetInterface("IEnumerable", false) != null;
    }
    /// <summary>
    /// 判断是否为数组
    /// </summary>
    /// <param name="p"></param>
    /// <returns></returns>
    private static bool IsArray(PropertyInfo p)
    {
        return p.PropertyType.IsArray;
    }
    /// <summary>
    /// 判断是否为字典
    /// </summary>
    /// <param name="p"></param>
    /// <returns></returns>
    private static bool IsDictionary(PropertyInfo p)
    {
        return typeof(IDictionary).IsAssignableFrom(p.PropertyType);
    }

    /// <summary>
    /// 判断是否为集合
    /// </summary>
    /// <param name="p"></param>
    /// <returns></returns>
    private static bool IsList(PropertyInfo p)
    {
        return typeof(IList).IsAssignableFrom(p.PropertyType);
    }
}

 

 

 

使用参考

/// <summary>
/// 测试Formdata向Model转换
/// </summary>
/// <param name="formData"></param>
/// <returns></returns>
[HttpPost]
public IActionResult FormDataToModel([FromForm]IFormCollection formData)
{
    var view = new TestModel();
    FormDataHelper.ToModel(ref view, formData);
    return new JsonResult(view);//vs调试断点打在这里
}
class TestModel
{
    public int[] IntArr { get; set; }
    public double[] DoubleArr { get; set; }
    public float[] FloatArr { get; set; }
    public string[] StringArr { get; set; }
    public int IntVal { get; set; }
    public string StringVal { get; set; }
    public double DoubleVal { get; set; }
    public float FloatVal { get; set; }
    public DateTime DateTimeVal { get; set; }
}

 

 

测试方法(未写前台代码,用postman测试的,原理是相同的)

 

 

 

 转换结果(vs调试断点处,使用快速监视,查看view对象的数据如图)

 

 

 

 

 

TODO:

后续研究一下需要增加List类型或字典的转换

posted @ 2021-05-13 12:31  五兆  阅读(123)  评论(0编辑  收藏  举报