如何使绑定到 Nullable<int> 属性的 DropDownListFor 接受空值?

Posted

技术标签:

【中文标题】如何使绑定到 Nullable<int> 属性的 DropDownListFor 接受空值?【英文标题】:How to make a DropDownListFor bound to a Nullable<int> property accept an empty value? 【发布时间】:2014-03-04 21:23:51 【问题描述】:

我在 ASP.NET MVC cshtml 页面中有以下 DropDownList:

@Html.DropDownListFor(model => model.GroupId, (IEnumerable<SelectListItem>)ViewBag.PossibleGroups, "")

属性定义为public virtual Nullable&lt;int&gt; GroupId

虽然GroupIdNullable,但select 菜单不会接受空选项。如果我尝试在不选择组的情况下保存模型,则会收到以下错误消息:

GroupId 字段必须是数字。

选择菜单呈现如下:

<select data-val="true" data-val-number="The field GroupId must be a number." id="GroupId" name="GroupId" class="input-validation-error" data-hasqtip="0" aria-describedby="qtip-0">
    <option value=""></option>
    <option value="1">Test Group</option>
</select>

不,GroupId 没有用 [Required] 属性修饰。

如何使页面接受GroupId 的空值?

附: GroupId 类型 (Nullable&lt;int&gt;) 是代码生成的。我使用数据库优先方案。我不知道&lt;Nullable&gt;intint 有什么区别?

更新

即使空选择项的值为零也不会通过非干扰 (javascript) 验证。但是,设置 -1 的值会通过客户端和服务器端的验证。所以现在,我正在使用这个值,在控制器中,如果它等于-1,我将GroupId 设置为null

我不敢相信这样一个简单的问题没有更简单的解决方案。这是 ASP.NET MVC 3 中的错误吗?

【问题讨论】:

GroupId 是否被其他属性修饰过? 【参考方案1】:

为模型绑定创建类

 public class BindDropDown

    public Nullable<int> ID get; set; 
    [Required(ErrorMessage = "Enter name")]
    public string Name get; set;  

创建控制器

    namespace DropDown.Controllers
  
public class HomeController : Controller

    public ActionResult Index()
    
        ViewBag.Message = "Welcome to ASP.NET MVC!";

        ViewBag.InterviewList = NumberList;

        return View(new BindDropDown());
    
    [HttpPost]
    public ActionResult Index(BindDropDown d)
    
        if (ModelState.IsValid)
        
            ViewBag.Message = "Welcome to ASP.NET MVC!";
        
        else
        
            ViewBag.Message = "error";
        
        ViewBag.NumberList = NumberList;

        return View(new BindDropDown());
    

    public ActionResult About()
    
        return View();
    

    public static IEnumerable<SelectListItem> NumberList
    
        get
        
            IEnumerable<NumberClass> interviewAppeals = Enum.GetValues(typeof(NumberClass))
                                                  .Cast<NumberClass>();
            return from item in interviewAppeals
                   select new SelectListItem
                   
                       Text = item.ToString(),
                       Value = ((int)item).ToString()
                   ;

        
    


public enum NumberClass

    One = 1,
    Two = 2,
    Three = 3

 

索引.cshtml

@using DropDown.Models
@model BindDropDown
@
ViewBag.Title = "Home Page";
 

<h2>@ViewBag.Message</h2>
<p>

</p>
@using (Html.BeginForm("Index", "Home", FormMethod.Post, new  id =   "frmOnline" ))


@Html.ValidationSummary(false)   


<div class="w100">
    <div class="fleft">
        <label>ID :</label>
    </div>
    <div class="fleft">
        @Html.DropDownListFor(model => model.ID, (IEnumerable<SelectListItem>)ViewBag.NumberList, "")

    </div>
</div> 
<div class="w100">
    <div class="fleft">
        <label>Name :</label>
    </div>
    <div class="fleft">
        @Html.TextBoxFor(model => model.Name)
        @Html.ValidationMessageFor(model => model.Name)

    </div>
</div> 
<div class="w100 clear">
    <label>&nbsp;</label>
    <div class="fleft">
        <input type="submit" value="Save" class="button green" />
        @Html.ActionLink("Back", "GetAllAction", null, new  @class = "button gray" )

    </div>
</div> 

【讨论】:

【参考方案2】:

尝试在下拉列表中显示空白值

型号

public class Products 
public int pid get;set;
public String sValue get; set;

控制器

    List<Products> lstProducts = new List<Products>()
    
    new Products() pid=0, sValue="",
    new Products() pid=1, sValue="One",
    new Products() pid=2, sValue="Two"
    ;

ViewBag.products = new SelectList(lstProducts, "pid", "sValue");

查看

@Html.DropDownList("products",@ViewBag.products as List<SelectListItems>)

【讨论】:

以上是关于如何使绑定到 Nullable<int> 属性的 DropDownListFor 接受空值?的主要内容,如果未能解决你的问题,请参考以下文章

无法将 Null 值分配给 Nullable Int32?通过绑定

Nullable<int> 是“预定义的值类型”吗?或者 Equals() 和 == 如何在这里工作?

Nullable<T> 的内存占用是多少

为啥 GetType 返回 System.Int32 而不是 Nullable<Int32>? [复制]

术语:您如何描述 Nullable<T> 的类型 T?

C#--可空类型(Nullable)