Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.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/0/asp.net-mvc/17.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
C# Html.EnumDropdownListFor:显示默认文本_C#_Asp.net Mvc_Drop Down Menu_Asp.net Mvc 5.1 - Fatal编程技术网

C# Html.EnumDropdownListFor:显示默认文本

C# Html.EnumDropdownListFor:显示默认文本,c#,asp.net-mvc,drop-down-menu,asp.net-mvc-5.1,C#,Asp.net Mvc,Drop Down Menu,Asp.net Mvc 5.1,在我看来,我有一个新特性(Asp.NETMVC5.1中的一个新特性) 如果我执行上述代码,我将获得以下枚举的dropdownlist public enum LicenseTypes { Trial = 0, Paid = 1 } 但默认情况下,我希望dropdownlist有一个值(自定义文本) 这就是我试过的 @Html.EnumDropDownListFor(m => m.SelectedLicense,"Select a license" ,new { @clas

在我看来,我有一个新特性(Asp.NETMVC5.1中的一个新特性)

如果我执行上述代码,我将获得以下枚举的dropdownlist

public enum LicenseTypes
{
    Trial = 0,
    Paid = 1
}
但默认情况下,我希望dropdownlist有一个值(自定义文本) 这就是我试过的

@Html.EnumDropDownListFor(m => m.SelectedLicense,"Select a license" ,new { @class="form-control"})
但现在的问题是,当我运行它时,我的dropdownlist如下所示 因此,我要显示的默认文本在默认情况下不会显示。 如果用户选择“选择许可证”并尝试提交表单,它确实会显示一个错误,显示为“选择许可证”,但不会显示为默认文本。 我需要改变什么


Ps:图像是页面加载时的屏幕截图。默认情况下,它会将试用显示为选中选项。

尝试更改
许可证类型的
索引
,从
1
开始,而不是
0
,如下所示:

public enum LicenseTypes
{
    Trial = 1,
    Paid = 2
}
public class YourViewModel
{
     //Other properties
     [Range(1,int.MaxValue,ErrorMessage = "Select a correct license")]
     public LicenseTypes LicenseTypes { get; set; }
}
然后,您可以使用
范围属性
验证所选许可证类型,如下所示:

public enum LicenseTypes
{
    Trial = 1,
    Paid = 2
}
public class YourViewModel
{
     //Other properties
     [Range(1,int.MaxValue,ErrorMessage = "Select a correct license")]
     public LicenseTypes LicenseTypes { get; set; }
}
最后,你认为:

   @Html.EnumDropDownListFor(m => m.LicenseTypes,"Select a license",new { @class = "form-control"})
   @Html.ValidationMessageFor(m => m.LicenseTypes)

当呈现您的
EnumDropDownList for
时,
SelectedLicense
已具有该类型的默认值,即
0

只需将
SelectedLicense
属性的类型更改为可为空的枚举,如下所示:

public LicenseTypes? SelectedLicense { get; set; }
这还允许您继续使用
Required
属性,我认为这非常干净。
Required
属性将不允许空响应,因此即使您的模型允许空响应,表单也不会。

我有一个枚举:

public enum Sex
{
    Male,
    Female
}
在我的模型中,我有:

    [DisplayName("Sex")]
    [Required]
    public Sex? Sex { get; set; }
一种观点认为:

    @Html.EnumDropDownListFor(model => model.Sex, "Select sex", new { @class = "form-control", type = "text"})
这样我就有了一个带有默认选项“selectsex”的下拉列表,但验证只接受enum提供的选项(“男性”和“女性”)

在模型中使用的MVC3(不带EnumDropDownlostFor)中:

    [DisplayName("Sex")]
    [Required(AllowEmptyStrings=false)]
    public Sex? Sex { get; set; }

    Sex = null;

    Sexes = Repository.GetAutoSelectList<Sex>("");

ViewModel类需要在enum属性上设置默认值,才能作为默认选择 公开的

控制器:

 public class EnumController : Controller
    {
        // GET: Enum
        public ActionResult Index()
        {
            var model = new Test {MyCars = Test.Cars.Car3}; // set default value
            return View(model);
        }
        [HttpPost]
        public ActionResult Index(Test model)
        {
            .....
        }
    }
namespace WebApplication1.Controllers {
    public class FanController : Controller {
        public ActionResult Index() {
            ViewBag.FavouriteMusic = string.Empty;
            //ModelState.SetModelValue( "FavouriteMusic", new ValueProviderResult( string.Empty, string.Empty, System.Globalization.CultureInfo.InvariantCulture ) );
            return View( "Index" );
        }
        [HttpPost, ActionName( "Index" )]
        public ActionResult Register( Models.Fan newFan ) {
            if( !ModelState.IsValid )
                return View( "Index" );
            ModelState.Clear();
            ViewBag.Message = "OK - You may register another fan";
            return Index();
        }
    }
}
视图:

@Html.BeginForm()
{
枚举类型
@EnumDropDownListFor(model=>model.MyCars)
}
我是不是有点晚了

更改枚举类型的值不是很令人满意

也不是更改模型属性以使其可为null,然后添加[Required]属性以防止其为null

我建议使用ViewBag设置下拉列表的默认选定值。 下面控制器的第4行是唯一重要的一行。

编辑:啊。。。新手。。。我的第一个想法是使用ModelState.SetModelValue,因为我的新手本能阻止我简单地尝试在ViewBag中设置所需的值,因为下拉列表绑定到模型。我肯定会遇到一个问题:它将绑定到模型的属性,而不是ViewBag的属性。我完全错了:ViewBag还可以。我更正了代码

这里有一个例子

型号:

namespace WebApplication1.Models {

    public enum GoodMusic {
        Metal,
        HeavyMetal,
        PowerMetal,
        BlackMetal,
        ThashMetal,
        DeathMetal // . . .
    }

    public class Fan {
        [Required(ErrorMessage = "Don't be shy!")]
        public String Name { get; set; }
        [Required(ErrorMessage = "There's enough good music here for you to chose!")]
        public GoodMusic FavouriteMusic { get; set; }
    }
}
控制器:

 public class EnumController : Controller
    {
        // GET: Enum
        public ActionResult Index()
        {
            var model = new Test {MyCars = Test.Cars.Car3}; // set default value
            return View(model);
        }
        [HttpPost]
        public ActionResult Index(Test model)
        {
            .....
        }
    }
namespace WebApplication1.Controllers {
    public class FanController : Controller {
        public ActionResult Index() {
            ViewBag.FavouriteMusic = string.Empty;
            //ModelState.SetModelValue( "FavouriteMusic", new ValueProviderResult( string.Empty, string.Empty, System.Globalization.CultureInfo.InvariantCulture ) );
            return View( "Index" );
        }
        [HttpPost, ActionName( "Index" )]
        public ActionResult Register( Models.Fan newFan ) {
            if( !ModelState.IsValid )
                return View( "Index" );
            ModelState.Clear();
            ViewBag.Message = "OK - You may register another fan";
            return Index();
        }
    }
}
视图:

@model WebApplication1.Models.Fan
你好,范
@使用(Html.BeginForm()){
@LabelFor(m=>m.Name)

@Html.EditorFor(m=>m.Name)@Html.ValidationMessageFor(m=>m.Name)

@LabelFor(m=>m.favoritemusic)

@Html.EnumDropDownListFor(m=>m.FavoriteMusic,“从这里选择您喜爱的音乐…”)@Html.ValidationMessageFor(m=>m.FavoriteMusic)

@查看包。留言 }

有效,但它将添加
选择一个许可证
作为id为0的枚举值之一。当用户没有从枚举中选择一个值时,我希望能够显示错误消息。我可以这样做,但我会让它在一段时间内不被接受,然后看看是否有人能提供更好的解决方案,直到+1表示您的想法。@probackpacker有更好的答案,这个选项不会在验证过程中被发现。我认为这是目前最好的答案,但它看起来像是一个黑客。真正的解决方案应该在MVC内部,以便正确处理不可为空的枚举。@jhilden,我认为MVC正是按照您的要求正确处理不可为空的枚举。在.NET中。假设您将属性类型保留为不可为空的枚举(
LicenseTypes
),并在发布表单时选择了“选择许可证”(没有值的列表项)。您的
SelectedLicense
属性将以默认值(
Trial
)结束。如果您刚刚检查了模型,它将无法与用户实际选择的
试用值区分开来。您是正确的。我回顾了我的另一个代码,如果我们想要一个int是必需的,但没有默认值,那么我们需要:[必需]public int?NullableIntHere{get;set;}@shim:它适用于从主视图调用的部分视图,但不适用于在AJAX中调用的部分视图。局部视图获取主视图ViewBag的副本。当主视图调用部分视图时,确实会执行索引操作。当AJAX请求调用局部视图时,您不会这样做。Index.cshtml:
@model WebApplication1.Models.Fan
<h2>Hello, fan</h2>
@using( Html.BeginForm() ) {
    <p>@Html.LabelFor( m => m.Name )</p>
    <p>@Html.EditorFor( m => m.Name ) @Html.ValidationMessageFor( m => m.Name )</p>
    <p>@Html.LabelFor( m => m.FavouriteMusic )</p>
    <p>@Html.EnumDropDownListFor( m => m.FavouriteMusic, "Chose your favorite music from here..." ) @Html.ValidationMessageFor( m => m.FavouriteMusic )</p>
    <input type="submit" value="Register" />
    @ViewBag.Message
}