[C#]Model or List To RouteValueDictionary
有時候我們在使用Url.Action()的時候會想要new{}一些 參數帶回Controller HttpGet的Action,如果需要帶回的參數越多,我們要手動bind就越麻煩,這時候我就在想可不可以直接寫一個擴充方法,把事先組好的model 轉為 RouteValueDictionary 直接帶入Url.Action()裡。
範例:
*測試用模型(盡可能測試各種TYPE)
public class UrlTestModel { public string Str { get; set; } public bool Bol { get; set; } public DateTime Date { get; set; } public List<UrlSubModel> List { get; set; } public UrlSubModel[] Array { get; set; } public int[] IntArray { get; set; } } public class UrlSubModel { public string Name { get; set; } }
1.建立一個UrlHelper
ps:「paramName」只有在如果controller需要接的參數是個List或Array的時候,才需要帶入參數名稱給這個「paramName」。
public static class UrlHelper { /// <summary> /// 轉換 Model To RouteValueDictionary /// </summary> /// <typeparam name="T"></typeparam> /// <param name="obj"></param> /// <param name="paramName">參數名稱(若 類型為List 須給 binding的名稱)</param> /// <returns></returns> public static RouteValueDictionary ModelToRouteValueDictionary<T>(T obj,string paramName=default) { var rvDic = new RouteValueDictionary(); if (obj == null) { return rvDic; } var type = obj.GetType(); if ((type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>)) || typeof(ICollection).IsAssignableFrom(type) || typeof(Object[]).IsAssignableFrom(type)) { var list= obj as IEnumerable; var index = 0; foreach (var item in list) { var value = GetObjectRouteValueDictionary(item); foreach (var subItem in value) { rvDic.Add($"{paramName}[{index}].{subItem.Key}", subItem.Value); } index++; } return rvDic; } rvDic = GetObjectRouteValueDictionary(obj); return rvDic; } /// <summary> /// 取得物件 RouteValueDictionary /// </summary> /// <typeparam name="T"></typeparam> /// <param name="obj"></param> /// <returns></returns> private static RouteValueDictionary GetObjectRouteValueDictionary<T>(T obj) { var rvDic = new RouteValueDictionary(); var type = obj.GetType(); var properties = type.GetProperties(); for (var i = 0; i < properties.Length; i++) { var property = properties[i]; var propertyType = property.PropertyType; if ((propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) || typeof(ICollection).IsAssignableFrom(propertyType) || typeof(Object[]).IsAssignableFrom(propertyType)) { IEnumerable list = (IEnumerable)property.GetValue(obj); if (list == null) { continue; } var index = 0; foreach (var item in list) { var subpropertyName = string.Concat(property.Name, "[", index, "]"); var subproperties = item.GetType().GetProperties(); if (subproperties != null && subproperties.Any()) { var subValue = GetObjectRouteValueDictionary(item); foreach (var subItem in subValue) { rvDic.Add($"{subpropertyName}.{subItem.Key}", subItem.Value); } index++; continue; } rvDic.Add(subpropertyName, item); index++; } continue; } var propertyValue = property.GetGetMethod().Invoke(obj, null); if (propertyValue == null) { continue; } rvDic.Add(property.Name, propertyValue); } return rvDic; } }
2.測試 html code
<button onclick="TestFunc();">測試物件轉換成RouteValueDictionary</button> <button onclick="TestListFunc();">測試物件轉換成List RouteValueDictionary</button> @{ //單一模型 var data = ViewData["TestData"] as MVCTest.Helpers.UrlHelper.UrlTestModel; //List var list = ViewData["TestList"] as List<MVCTest.Helpers.UrlHelper.UrlTestModel>; } @*Action 單一模型URL*@ @Html.Hidden("TESTUrl", Url.Action("TestUrl", "Home", UrlHelper.ModelToRouteValueDictionary(data))) @*Action List*@ @Html.Hidden("TESTListUrl", Url.Action("TestListUrl", "Home", UrlHelper.ModelToRouteValueDictionary(list, "data")))
*ViewData Set Value
var sublist = new List<UrlSubModel>() { new UrlSubModel() { Name="A" }, new UrlSubModel() { Name="B" } }; var model = new UrlTestModel() { Str = "Test", Date = DateTime.Now, List = sublist, Array = sublist.ToArray(), IntArray = new int[] { 1, 2 } }; ViewData["TestData"] = model; var list = new List<UrlTestModel>(); list.Add(model); list.Add(model); ViewData["TestList"] = list;
3.JavaScript Code
<script> //單一模型 function TestFunc() { window.location.href = $('#TESTUrl').val(); } //List function TestListFunc() { window.location.href = $('#TESTListUrl').val(); } </script>
4.結果
(1) Action 單一模型 結果
(2)Action List 結果
留言
張貼留言