2015年7月28日 星期二

[MVC] IEnumerable Extensions

 C#   MVC  


背景

MVC中,因時常會使用到將預設選項以IEnumerable<SelectListItem> 的型態BindingDropDownList Helper,搜尋找到一版滿完整的IEnumerableExtensions,因此紀錄一下使用方式。



練習


View

<div class="col-md-10">
@Html.DropDownListFor(model => model.Sex, (IEnumerable<SelectListItem>)ViewData["SexSelectList"],
new { htmlAttributes = new { @class = "form-control" } })

@Html.ValidationMessageFor(model => model.Sex, "", new { @class = "text-danger" })
</div>


IEnumerable Extensions

/// <summary>
    /// IEnumerable Extensions
    /// </summary>
    public static class IEnumerableExtensions
    {
        /// <summary>
        ///
        /// </summary>
        /// <param name="values"></param>
        /// <returns></returns>
        public static string JoinString(this IEnumerable<string> values)
        {
            return JoinString(values, ",");
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="values"></param>
        /// <param name="split"></param>
        /// <returns></returns>
        public static string JoinString(this IEnumerable<string> values, string split)
        {
            var result = values.Aggregate(string.Empty, (current, value) => current + (split + value));
            result = result.TrimStart(split.ToCharArray());
            return result;
        }

        /// <summary>
        /// Do somthing for each item in the IEnumerable
        /// </summary>
        /// <typeparam name="T">Type</typeparam>
        /// <param name="source">Source IEnumerable</param>
        /// <param name="action">Action for doing something</param>
        /// <returns>IEnumerable</returns>
        public static IEnumerable<T> Each<T>(this IEnumerable<T> source, Action<T> action)
        {
            if (source != null)
            {
                foreach (var item in source)
                {
                    action(item);
                }
            }
            return source;
        }

        /// <summary>
        /// Convert IEnumerable to IList<SelectListItem>
        /// </summary>
        /// <typeparam name="T">Type</typeparam>
        /// <param name="source">IEnumerable</param>
        /// <param name="text">Func for display text of IEnumerable</param>
        /// <param name="value">Func for value of IEnumerable</param>
        /// <returns>IList of SelectListItem</returns>
        public static IList<SelectListItem> ToSelectList<T>(
            this IEnumerable<T> source, Func<T, object> text, Func<T, object> value, bool isOrder = false)
        {
            return source.ToSelectList(text, value, null, null);
        }

        /// <summary>
        /// Convert IEnumerable to IList<SelectListItem>
        /// </summary>
        /// <typeparam name="T">Type</typeparam>
        /// <param name="source">IEnumerable</param>
        /// <param name="text">Func for display text of IEnumerable</param>
        /// <param name="value">Func for value of IEnumerabl</param>
        /// <param name="optionalText">Extra option</param>
        /// <returns>IList of SelectListItem</returns>
        public static IList<SelectListItem> ToSelectList<T>(
            this IEnumerable<T> source, Func<T, object> text, Func<T, object> value,
            string optionalText, bool isOrder = false)
        {
            return source.ToSelectList(text, value, null, optionalText, isOrder);
        }

        /// <summary>
        /// Convert IEnumerable to IList<SelectListItem>
        /// </summary>
        /// <typeparam name="T">Type</typeparam>
        /// <param name="source">IEnumerable</param>
        /// <param name="text">Func for display text of IEnumerable</param>
        /// <param name="value">Func for value of IEnumerabl</param>
        /// <param name="selected">Func for Seleced item</param>
        /// <returns>IList of SelectListItem</returns>
        public static IList<SelectListItem> ToSelectList<T>(
            this IEnumerable<T> source, Func<T, object> text, Func<T, object> value,
            Func<T, bool> selected, bool isOrder = false)
        {
            return source.ToSelectList(text, value, selected, null);
        }


        /// <summary>
        /// Convert IEnumerable to IList<SelectListItem>
        /// </summary>
        /// <typeparam name="T">Type</typeparam>
        /// <param name="source">IEnumerable</param>
        /// <param name="text">Func for display text of IEnumerable</param>
        /// <param name="value">Func for value of IEnumerabl</param>
        /// <param name="selected">Func for Seleced item</param>
        /// <param name="optionalText">Extra option</param>
        /// <returns>IList of SelectListItem</returns>
        public static IList<SelectListItem> ToSelectList<T>(
            this IEnumerable<T> source, Func<T, object> text, Func<T, object> value,
            Func<T, bool> selected, string optionalText, bool isOrder = false)
        {
            return source.ToSelectList(text, value, selected, optionalText, string.Empty, isOrder);
        }


        /// <summary>
        /// Core function for EnumerableExtension.cs
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source"></param>
        /// <param name="text"></param>
        /// <param name="value"></param>
        /// <param name="selected"></param>
        /// <param name="optionalText"></param>
        /// <param name="optionalValue"></param>
        /// <returns></returns>
        private static IList<SelectListItem> ToSelectList<T>(
            this IEnumerable<T> source, Func<T, object> text, Func<T, object> value,
            Func<T, bool> selected, string optionalText, string optionalValue, bool isOrder = false)
        {
            var items = new List<SelectListItem>();

            //預設會先加入optionalText
            if (!string.IsNullOrEmpty(optionalText))
            {
                items.Insert(0, new SelectListItem() { Text = optionalText, Value = optionalValue });
            }

            if (source == null)
            {
                return items;
            }


            foreach (var entity in source)
            {
                var item = new SelectListItem();
                item.Text = text(entity).ToString();
                item.Value = value(entity).ToString();
                if (selected != null)
                {
                    item.Selected = selected(entity);
                }

                if (item.Value != optionalValue)
                {
                    items.Add(item);
                }
            }

            if (isOrder)
            {
                items = items.OrderBy(d => d.Text).ToList();           
            }

            return items;
        }
    }


 Controller

Controller中自行建立(或拉回)有”Male””Female”的資料如下:
Key
Value
1
Male
2
Female

UnitTest codes in controller (Of course you have to comment out the non-testing codes by urself) :
public ActionResult Create()
{


            //Given "Text" and "Value" to the IList<SelectListItem>
            ViewData["SexSelectList"] =
                sexList.AsEnumerable().ToSelectList(x => x.Value, x => x.Key);
            //Set isOrder = true
            ViewData["SexSelectList"] =
                sexList.AsEnumerable().ToSelectList(x => x.Value, x => x.Key, isOrder: true);
            //Set the default selected value in IList<SelectListItem>
            ViewData["SexSelectList"] =
                sexList.AsEnumerable().ToSelectList(x => x.Value, x => x.Key, x => x.Value.Equals("Female"));
            //Add a new item : "Please select ..." to IList<SelectListItem>
            ViewData["SexSelectList"] =
                sexList.AsEnumerable().ToSelectList(x => x.Value, x => x.Key, "Please select ...");
            //Set the default selected value and add a new item in IList<SelectListItem>
            ViewData["SexSelectList"] =
                sexList.AsEnumerable().ToSelectList(x => x.Value, x => x.Key, x => x.Value.Equals("Male"), "Please select ...");
            //Do an action for every item in IList<SelectListItem>
            ViewData["SexSelectList"] = sexList.AsEnumerable()
                .Each(x => x.Value = (x.Value.Equals("Male") ? (x.Value + "()") : (x.Value + "()")))
                .ToSelectList(x => x.Value, x => x.Key);


            return View();
}

//Given "Text" and "Value" to the IList<SelectListItem>

//Set isOrder = true

//Set the default selected value in IList<SelectListItem>

//Add a new item : "Please select ..." to IList<SelectListItem>

//Set the default selected value and add a new item in IList<SelectListItem>


//Do an action for every item in IList<SelectListItem>
 















沒有留言:

張貼留言