C# Html.EnumDropdownListFor:显示默认文本
在我看来,我有一个新特性(Asp.NETMVC5.1中的一个新特性) 如果我执行上述代码,我将获得以下枚举的dropdownlistC# 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
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
}