【问题标题】:Get comma-separated string from CheckboxList HTML Helper从 CheckboxList HTML Helper 获取逗号分隔的字符串
【发布时间】:2015-04-02 05:26:14
【问题描述】:

我从互联网上获得了以下代码,用于CheckboxListFor html 帮助程序扩展。目前,在SelectedValues 中,它正在返回复选框列表中选定值的List<string>。我想在SelectedValues 中得到一个逗号分隔的字符串。

谁能告诉我如何实现它?

代码如下:

HTMLHelper 扩展:

        /// <summary>
    /// Returns a checkbox for each of the provided <paramref name="items"/>.
    /// </summary>
    public static MvcHtmlString CheckBoxList(this HtmlHelper htmlHelper, string listName, IEnumerable<SelectListItem> items, object htmlAttributes = null)
    {
        var container = new TagBuilder("div");
        foreach (var item in items)
        {
            var label = new TagBuilder("label");
            label.MergeAttributes(new RouteValueDictionary(htmlAttributes), true);

            var cb = new TagBuilder("input");
            cb.MergeAttribute("type", "checkbox");
            cb.MergeAttribute("name", listName);
            cb.MergeAttribute("value", item.Value ?? item.Text);
            if (item.Selected)
                cb.MergeAttribute("checked", "checked");

            label.InnerHtml = cb.ToString(TagRenderMode.SelfClosing) + item.Text;

            container.InnerHtml += label.ToString();
        }

        return new MvcHtmlString(container.ToString());
    }

    private static IEnumerable<SelectListItem> GetCheckboxListWithDefaultValues(object defaultValues, IEnumerable<SelectListItem> selectList)
    {
        var defaultValuesList = defaultValues as IEnumerable;

        if (defaultValuesList == null)
            return selectList;

        IEnumerable<string> values = from object value in defaultValuesList
                                     select Convert.ToString(value, CultureInfo.CurrentCulture);

        var selectedValues = new HashSet<string>(values, StringComparer.OrdinalIgnoreCase);
        var newSelectList = new List<SelectListItem>();

        selectList.ForEach(item =>
        {
            item.Selected = (item.Value != null) ? selectedValues.Contains(item.Value) : selectedValues.Contains(item.Text);
            newSelectList.Add(item);
        });

        return newSelectList;
    }

    /// <summary>
    /// Returns a checkbox for each of the provided <paramref name="items"/>.
    /// </summary>
    public static MvcHtmlString CheckBoxListFor<TModel, TValue>(this HtmlHelper<TModel> htmlHelper, 
        Expression<Func<TModel, TValue>> expression, 
        IEnumerable<SelectListItem> items, object htmlAttributes = null)
    {
        var listName = ExpressionHelper.GetExpressionText(expression);
        var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);

        items = GetCheckboxListWithDefaultValues(metaData.Model, items);
        return htmlHelper.CheckBoxList(listName, items, htmlAttributes);
    }

在视图中:

@Html.CheckBoxListFor(model => model.SelectedValues, Model.MySelectList)

型号:

public class MyViewModel
{        
      public SelectList MySelectList{ get; set; }

      public List<string> SelectedValues{ get; set; }

      //public string SelectedValues{ get; set; }   Can I get comma separated string here
}

请注意,我需要从帮助程序返回的逗号分隔字符串,而不是在我获得控制器操作的返回列表之后。

我为什么要这样做?:

//Here in my model, I am getting `SelectedValues` which is a List<String>.
public ActionResult Index(MyViewModel model)
{
      //My code....
}

可见

//But I cannot save this list into RouteValueDictionary like:
var searchCriteria = new RouteValueDictionary();
searchCriteria["model.SelectedValues"] = Model.SelectedValues; // List<string> cannot be save here. That's why I needed comma separated string.
var viewDataDictionary = new ViewDataDictionary();
viewDataDictionary["searchCriteria"] = searchCriteria;

@Html.Partial("_MyPagingView", Model.MyList, viewDataDictionary)

_MyPagingView 内部有一个完整的机制,每当单击下一页时,它都会调用Index Action。为了保留搜索的状态,我们需要将搜索到的数据保存在 RouteValueDictionary 中。

【问题讨论】:

  • string.join 应该放在哪里?请注意,我需要从帮助程序返回的逗号分隔字符串,而不是在我取回列表之后。
  • 你的助手正在生成一系列同名的复选框。它只能回发数组或值。您需要在服务器上生成逗号分隔的字符串,或者在发布之前使用 javascript 构建字符串并更新隐藏的输入。
  • @UsmanKhalid 您可以在控制器操作中使用string.Join
  • @StephenMuecke 我已经在使用 javascript 和隐藏值。我只是想知道是否可以在没有额外的 javascript 代码的情况下获得它。

标签: c# .net asp.net-mvc html-helper


【解决方案1】:

您可以创建一个辅助方法来将SelectedValues 添加到RouteValueDictionary

public void AddRoutes(List<string> values, string propertyName, RouteValueDictionary dictionary)
{
    for (int i = 0; i < values.Count; i++ )
    {
        string key = string.Format("{0}[{1}]", propertyName, i);
        dictionary[key] = values[i];
    }
}

然后将其用作

var searchCriteria = new RouteValueDictionary();
AddRoutes(Model.SelectedValues, "SelectedValues", searchCriteria);

并避免创建隐藏输入和使用 javascript

【讨论】:

    【解决方案2】:

    我更喜欢更改视图模型的代码:

    public class MyViewModel
    {
        public SelectList MySelectList{ get; set; }
    
        public List<string> SelectedValues { get; set; }
    
        public string SelectedString
        {
            get
            {
                if (SelectedValues == null) return "";
                return string.Join(",", SelectedValues);
            }
            set
            {
                if (!string.IsNullOrEmpty(value))
                {
                    SelectedValues = value.Split(',').ToList();
                }
            }
        }
    }
    

    你可以得到逗号分隔的字符串:

    //In controller
    var selected = model.SelectedString; 
    
    //In view
    searchCriteria["model.SelectedValues"] = Model.SelectedString;
    

    【讨论】:

      猜你喜欢
      • 2011-09-07
      • 1970-01-01
      • 2012-05-19
      • 1970-01-01
      • 2019-05-08
      • 2017-06-06
      • 2017-07-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多