2011-01-25 147 views
7

我有一個簡單的下拉列表,列表中的第一個項目有一個空值。如果我不選擇列表中的任何內容,客戶端驗證將忽略它。我使用註釋屬性在模型上根據需要設置了該字段。ASP.Net MVC 3不顯眼的客戶端驗證不適用於下拉列表

@Html.DropDownListFor(model => Model.CCPayment.State, UnitedStatesStates.StateSelectList) 



[Required(ErrorMessage = "State is Required.")] 
    public string State 
    { 
     get 
     { 
      return _state; 
     } 
     set 
     { 
      _state = value; 
     } 
    } 

有什麼想法嗎?我錯過了什麼嗎?

+0

將複選框添加到該框中,我有一個必選的複選框,在未選中時不會高亮顯示爲錯誤字段。 – JBeckton 2011-01-25 23:37:46

+0

不是一個真正的答案,更多的解決方法,但你有沒有嘗試過使用IValidatableObject接口 - 現在可能會幫助你? – RichardW1001 2011-01-26 00:01:14

+3

我已經在使用IValidatableObject進行服務器端驗證。這是客戶端問題。我確實在codeplex上找到了這個http://aspnet.codeplex.com/workitem/7629 – JBeckton 2011-01-26 00:26:49

回答

4

您提供的信息太少,以至於我們無法查明問題所在。您可能忘記在視圖中包含適當的不顯眼的驗證腳本,但是誰知道?你沒有展示你的觀點。

這裏是一個完整的工作示例:

型號:

public class MyViewModel 
{ 
    [Required(ErrorMessage = "State is Required.")] 
    public string State { get; set; } 

    public IEnumerable<SelectListItem> States 
    { 
     get 
     { 
      return Enumerable.Range(1, 5).Select(x => new SelectListItem 
      { 
       Value = x.ToString(), 
       Text = "state " + x 
      }); 
     } 
    } 
} 

控制器:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     return View(new MyViewModel()); 
    } 

    [HttpPost] 
    public ActionResult Index(MyViewModel model) 
    { 
     return View(model); 
    } 
} 

查看:

@model AppName.Models.MyViewModel 
@{ 
    ViewBag.Title = "Home Page"; 
} 
<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script> 

@using (Html.BeginForm()) 
{ 
    @Html.LabelFor(x => x.State) 
    @Html.DropDownListFor(
     x => x.State, 
     new SelectList(Model.States, "Value", "Text"), 
     "-- Please select a state --" 
    ) 
    @Html.ValidationMessageFor(x => x.State) 
    <input type="submit" value="OK" /> 
} 

通知我們如何提供一個默認值該DropDownListFor助手作爲最後一個參數。這將在開始時插入一個選項空值和自定義文本,如果用戶不選擇一些狀態,所需的驗證器應該踢入。

8

它看起來像一個合法的錯誤,這裏是我在我的搜索找到了最好的解決辦法:

http://forums.asp.net/t/1649193.aspx

總之。您纏繞問題,DropDownListFor的來源,在自定義HTML擴展和手動檢索這樣不顯眼的客戶端驗證規則:

IDictionary<string, object> validationAttributes = htmlHelper. 
    GetUnobtrusiveValidationAttributes(
     ExpressionHelper.GetExpressionText(expression), 
     metadata 
    ); 

然後您傳遞到您的自定義幫助其他HTML屬性結合您validationAttributes字典你傳遞一起DropDownListFor

我使用的完整代碼(我有一個標籤,在那裏,你可以隨意去耦):

public static IHtmlString DropDownListWithLabelFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, string label, IEnumerable<SelectListItem> items, string blankOption, object htmlAttributes = null) 
{ 
    var l = new TagBuilder("label"); 
    var br = new TagBuilder("br"); 

    var metadata = ModelMetadata.FromLambdaExpression(expression, helper.ViewData); 
    var mergedAttributes = helper.GetUnobtrusiveValidationAttributes(ExpressionHelper.GetExpressionText(expression), metadata); 

    if (htmlAttributes != null) 
    { 
     foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(htmlAttributes)) 
     { 
      object value = descriptor.GetValue(htmlAttributes); 
      mergedAttributes.Add(descriptor.Name, value); 
     } 
    } 

    l.InnerHtml = label + br.ToString(TagRenderMode.SelfClosing) + helper.DropDownListFor(expression, items, blankOption, mergedAttributes); 
    return MvcHtmlString.Create(l.ToString(TagRenderMode.Normal)); 
} 
1

這是我找到的最簡單的方法,只需在DropDownListForHtmlAttributes的視圖內添加data-val-*-*屬性即可。下面的方法與RemoteValidation工作也一樣,如果你不需要遠程驗證,只需刪除包含data-val-remote-*元素:

 @Html.DropDownListFor(m => m.yourlistID, (IEnumerable<SelectListItem>)ViewBag.YourListID, String.Empty, 
     new Dictionary<string, object>() { { "data-val", "true" }, 
     { "data-val-remote-url", "/Validation/yourremoteval" }, 
     { "data-val-remote-type", "POST" }, { "data-val-remote-additionalfield", "youradditionalfieldtovalidate" } }) 

我希望它可以幫助。最好的祝福!

相關問題