Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 选择具有数据属性的ListItem_Asp.net Mvc_Html_Html Helper_Custom Data Attribute_Selectlist - Fatal编程技术网

Asp.net mvc 选择具有数据属性的ListItem

Asp.net mvc 选择具有数据属性的ListItem,asp.net-mvc,html,html-helper,custom-data-attribute,selectlist,Asp.net Mvc,Html,Html Helper,Custom Data Attribute,Selectlist,是否需要在ViewModel上预先填充带有数据属性的SelectList 我想做什么 @Html.DropdownListFor(m=> m.CityId, Model.Cities); 因此,它生成如下代码: <select id="City" class="location_city_input" name="City"> <option data-geo-lat="-32.522779" data-geo-lng="-55.765835" data-geo

是否需要在ViewModel上预先填充带有数据属性的SelectList

我想做什么

@Html.DropdownListFor(m=> m.CityId, Model.Cities);
因此,它生成如下代码:

<select id="City" class="location_city_input" name="City">
    <option data-geo-lat="-32.522779" data-geo-lng="-55.765835" data-geo-zoom="6" />
    <option data-geo-lat="-34.883611" data-geo-lng="-56.181944" data-geo-zoom="13" data-geo-name="Montevideo" data-child=".state1" value="1">Montevideo</option>               
    <option data-geo-lat="-34.816667" data-geo-lng="-55.95" data-geo-zoom="13" data-geo-name="Canelones, Ciudad de la Costa" data-child=".state41" value="41">Ciudad de la Costa</option>
</select>

蒙得维的亚
海岸城

您必须扩展SelectListItem,然后扩展DropDownList for才能使用扩展的SelectListItem

看看这个解决方案:


以下是简单的解决方案

并非所有内容都必须在.NET代码中使用扩展方法编写。MVC的一大优点是,它使您能够轻松地构建自己的HTML

使用MVC4,您可以使用helpers和


@适用于模型中的每个城市。城市
@
@城市。文本
下一个
假设
Model.Cities
是一组项目,这些项目公开了每个属性。那你应该准备好了


如果你想重用,考虑将它作为一个可编辑的城市模板的模板< /p> < p>我有类似的要求,我创建了一个扩展名。希望它能帮助那些想要创建扩展的人

/*cs file*/
/*This contains your information with List<vmListItem>*/
public class vmListItem
{
   public int Id { get; set; }
   public string Name { get; set; }
   public string Tag { get; set; }
}

/*This contains the attributes in select, using List<vmAttribute>. Check cshtml */
public class vmAttribute
{
   public string Key { get; set; }
   public string Value { get; set; }
}

    /// <summary>
    /// Creates a dropdownlist using a list with data attributes included
    /// </summary>
    /// <param name="helper"></param>
    /// <param name="id">id and name of the select</param>
    /// <param name="attributes">list of attrs for select</param>
    /// <param name="items"><list of options/param>
    /// <param name="idSelected">id selected in option</param>
    /// <param name="tagName">data-tagName you can choose the name of your tag</param>
    /// <param name="textHeader">first option in select</param>
    /// <returns></returns>
    public static MvcHtmlString DropDownListForWithTag(this HtmlHelper helper, string id, List<vmAttribute> attributes, List<vmListItem> items, int idSelected, string tagName = "tag", string textHeader= "")
    {
        var select = new TagBuilder("select");
        select.GenerateId(id);
        select.MergeAttribute("name", id);
        foreach (vmAttribute att in atributos) select.MergeAttribute(att.Key, att.Value);

        TagBuilder headerOption = new TagBuilder("option");
        headerOption .MergeAttribute("value", null);
        headerOption .InnerHtml = textHeader;
        select.InnerHtml += headerOption ;

        foreach(var item in items)
        {                
            TagBuilder option = new TagBuilder("option");
            option.MergeAttribute("value", item.Id.ToString());
            option.MergeAttribute("data-" + tagName, item.Tag);
            if (idSelected == item.Id) option.MergeAttribute("selected", "selected");
            option.InnerHtml = item.Name;

            select.InnerHtml += option.ToString();
        }

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

/*cshtml file*/
@Html.DropDownListForWithTag("MovimientoBienMotivoId", new List<vmAttribute> {
                        new vmAttribute("class", "form-control"),
                        new vmAttribute("data-val", "true"),
                        new vmAttribute("data-val-required", "El campo Motivo es obligatorio"),
                        new vmAttribute("onchange", "movValidarCambioMotivo()"),
                    }, (List<vmListItem>)ViewBag.MovimientoBienMotivoId, Model.MovimientoBienMotivoId, "codigo", "Seleccione")
                    @Html.ValidationMessageFor(model => model.ColumnId, "", new { @class = "text-danger" })


/*html results*/
/*cs文件*/
/*这包含您的信息和列表*/
公共类vmListItem
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共字符串标记{get;set;}
}
/*它包含“使用列表选择”中的属性。检查cshtml*/
公共类属性
{
公共字符串密钥{get;set;}
公共字符串值{get;set;}
}
/// 
///使用包含数据属性的列表创建下拉列表
/// 
/// 
///选择对象的id和名称
///用于选择的属性列表
/// 
///在选项中选择的id
///数据标记名您可以选择标记的名称
///选择中的第一个选项
/// 
公共静态MvcHtmlString DropDownListForWithTag(此HtmlHelper帮助程序,字符串id,列表属性,列表项,int-idSelected,字符串标记名=“tag”,字符串textHeader=”“)
{
var select=新标记生成器(“选择”);
选择.GenerateId(id);
选择.MergeAttribute(“名称”,id);
foreach(atributos中的vmAttribute att)选择.MergeAttribute(att.Key,att.Value);
标记生成器标题选项=新标记生成器(“选项”);
headerOption.MergeAttribute(“值”,null);
headerOption.InnerHtml=textHeader;
select.InnerHtml+=headerOption;
foreach(项目中的var项目)
{                
标记生成器选项=新标记生成器(“选项”);
option.MergeAttribute(“value”,item.Id.ToString());
option.MergeAttribute(“数据-”+标记名,item.Tag);
if(idSelected==item.Id)option.MergeAttribute(“选定的”、“选定的”);
option.InnerHtml=item.Name;
select.InnerHtml+=option.ToString();
}
返回新的MvcHtmlString(select.ToString());
}
/*cshtml文件*/
@DropDownListForWithTag(“MoviMinoteBienMovioid”,新列表{
新属性(“类”、“窗体控件”),
新属性(“数据值”、“真”),
新的vmAttribute(“需要数据值”、“El campo动机和义务”),
新的vmAttribute(“onchange”、“movValidarkCambiomotivo()”,
},(列表)ViewBag.MOVIMINOTOBIENMOTIVOID,Model.MOVIMINOTOBIENMOTIVOID,“codigo”,“Seleccione”)
@Html.ValidationMessageFor(model=>model.ColumnId,“,new{@class=“text danger”})
/*html结果*/

MVC在将对象名称转换为属性名称时,会将“u”与“-”关联,因此:

不是我的答案,答案来自ASP>NET论坛的关于bruce(sqlwork.com)的文章


我只是想帮忙,因为这让我免于编写黑客代码!享受。

以下是我如何在没有扩展的情况下完成这项工作,但仍然能够使不引人注目的验证继续工作并绑定到ViewModel属性

创建了一个Html帮助程序,以获取字符串形式的验证属性:

    public static IHtmlString GetUnobtrusiveValidationAttributesFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> propertySelector)
    {
        string propertyName = html.NameFor(propertySelector).ToString();
        ModelMetadata metaData = ModelMetadata.FromLambdaExpression(propertySelector, html.ViewData);
        IDictionary<string, object> attributeCollection = html.GetUnobtrusiveValidationAttributes(propertyName, metaData);

        return html.Raw(String.Join(" ", attributeCollection.Select(kvp => kvp.Key + "=\"" + kvp.Value.ToString() + "\"")));
    }
这将输出如下内容:

<select id="CityId" name="CityId" 
    data-val-required="The SelectedTaxRateID field is required." data-val="true" 
    class="location_city_input">
    <option value="1" selected data-geo-lat="-34.883611" data-geo-lng="-56.181944" data-geo-zoom="13">Montevideo</option>               
    <option value="41" data-geo-lat="-34.816667" data-geo-lng="-55.95" data-geo-zoom="13">Ciudad de la Costa</option>
</select>

蒙得维的亚
海岸城

我将把条件
数据-
属性留给您,因为这些只是形成适当的Razor表达式的问题。

这看起来是正确的答案,但看起来有点难看。我宁愿自己编写select,也不愿扩展SelectListItem和DropDownListFor。我不确定。我不知道你为什么认为它难看,但我觉得它更符合逻辑。每个SelectListItem代表最终html中的一个选项标记,您需要做的是向选项标记(SelectListItem)添加自定义html属性,因此扩展SelectListItem才有意义。我认为从mvc框架的角度来看,这很难看。但解决方案正是如何处理的。同意,仅仅添加一些简单的属性就相当令人讨厌:(真的很难看的解决方案。最新版本(5.2)中有介绍过吗MVC版本,或者你仍然需要为此编写自定义代码?谢谢你的提醒…我不知道html.namefor等。我会给它一个非常好的建议,让它为你的html添加真正简单的灵活性。因为razor2你可以简单地做
selected=“@city.Value==Model.CityId”
,它将生成正确的标记(或者
selected=“选定的”
或“无”)如何使其在验证中仍然有效?当出现验证错误时,我的选择不再正确地以红色突出显示。由@Diego发布的代码在我添加括号之前不起作用:
selected=“@(city.Value==Model.CityId)“
谢谢您,这是最好的解决方案。我定制了此扩展以满足我的需要。这只是将数据rel添加到
选择
而不是每个
选项
中,很高兴知道,尽管它没有按需要添加属性(如ParoX所述)。
<select name="@Html.NameFor(m => m.CityId)" id="@Html.IdFor(m => m.CityId)"
    @Html.GetUnobtrusiveValidationAttributesFor(m => m.CityId)
    class="location_city_input">
    @foreach(var city in Model.Cities)
    {
        <option value="@city.Id.ToString()" @(city.Id == Model.CityId ? "selected" : "") 
            data-geo-lat="@city.Lat" data-geo-lng="@city.Lng" data-geo-zoom="@city.Zoom">
            @city.Name
        </option>
    }
</select>
<select id="CityId" name="CityId" 
    data-val-required="The SelectedTaxRateID field is required." data-val="true" 
    class="location_city_input">
    <option value="1" selected data-geo-lat="-34.883611" data-geo-lng="-56.181944" data-geo-zoom="13">Montevideo</option>               
    <option value="41" data-geo-lat="-34.816667" data-geo-lng="-55.95" data-geo-zoom="13">Ciudad de la Costa</option>
</select>