2011-01-25 35 views
7

Tôi có một danh sách thả xuống đơn giản, mục đầu tiên trong danh sách có giá trị trống. Nếu tôi không chọn bất cứ điều gì trong danh sách xác nhận khách hàng bỏ qua nó. Tôi đã thiết lập trường đó theo yêu cầu trên mô hình bằng cách sử dụng thuộc tính chú thích.ASP.Net MVC 3 xác nhận khách hàng không phô trương không hoạt động với danh sách thả xuống

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



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

bất kỳ ý tưởng nào? tui bỏ lỡ điều gì vậy?

+0

Thêm hộp kiểm vào đó, tôi có hộp kiểm bắt buộc không được chiếu sáng cao làm trường lỗi khi không được chọn. – JBeckton

+0

Không thực sự là một câu trả lời, nhiều hơn một workaround, nhưng có bạn đã thử bằng cách sử dụng giao diện IValidatableObject - có thể giúp bạn ra ngoài bây giờ? – RichardW1001

+3

Tôi đã sử dụng IValidatableObject để xác thực phía máy chủ. Đây là một vấn đề phía khách hàng. Tôi đã tìm thấy một vấn đề mở tại codeplex cho http://aspnet.codeplex.com/workitem/7629 – JBeckton

Trả lời

4

Bạn đã cung cấp quá ít thông tin để chúng tôi có thể xác định được sự cố. Bạn có thể đã quên bao gồm các tập lệnh xác thực không phô trương thích hợp trong chế độ xem của mình nhưng ai biết được? Bạn chưa hiển thị chế độ xem của mình.

Dưới đây là một ví dụ làm việc đầy đủ:

mẫu:

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 
      }); 
     } 
    } 
} 

Bộ điều khiển:

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

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

Xem:

@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" /> 
} 

Chú ý cách chúng tôi đang cung cấp một giá trị mặc định trong các DropDownListFor trợ giúp như tham số cuối cùng. Điều đó sẽ chèn một tùy chọn ở đầu với giá trị trống và văn bản tùy chỉnh và nếu người dùng không chọn một số trạng thái, trình xác thực được yêu cầu sẽ bắt đầu.

+0

nó nên kick in nhưng nó không, tôi đã cố gắng thêm giá trị mặc định nhưng tôi nhận được cùng một vấn đề. Cách duy nhất tôi có thể làm việc này là thêm 'required' vào thuộc tính class html. vấn đề là nó chỉ cung cấp một thông báo lỗi chung hơn là thông điệp tôi đã chỉ định trong thuộc tính xác thực mô hình của mình. – JBeckton

+0

Nó cũng bị vỡ cho tôi. Nếu tôi loại trừ jq.validate.js và chỉ bao gồm jq.validate.unobtrusive.js, nó hoạt động, đó là lạ. –

2

Tôi đã thêm @ class = "required" vào các thuộc tính như một số người đã nói trên thread tại CodePlex http://aspnet.codeplex.com/workitem/7629 và nó làm việc tốt cho tôi =)

+0

có đây là một công việc xung quanh nhưng bạn nhận được thông báo lỗi chung hơn là thông báo tùy chỉnh được xác định trong thuộc tính xác thực của bạn. – JBeckton

8

nó trông giống như một lỗi chính đáng, đây là cách giải quyết tốt nhất mà tôi đã tìm thấy trong tìm kiếm của tôi:

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

Nói tóm lại. Bạn quấn nguồn gốc của vấn đề, DropDownListFor, trong một phần mở rộng Html tùy chỉnh và bạn tự lấy quy tắc xác nhận clientside không phô trương như thế này:

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

Sau đó bạn kết hợp từ điển validationAttributes bạn với bất kỳ thuộc tính html khác thông qua vào helper tùy chỉnh của bạn và bạn qua đó cùng với DropDownListFor

Các mã hoàn chỉnh mà tôi đang sử dụng (tôi có một nhãn trong đó quá, bạn có thể cảm thấy tự do để de-couple):

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)); 
} 
+0

Ngoài tôi, đây không phải là câu trả lời được chấp nhận? +1 –

+0

Nghiêm túc đây chắc chắn là câu trả lời !!! Đã làm việc trên cái này trong ba ngày! Tôi sẽ không bao giờ tìm ra điều này. Tuyệt vời!!! Cảm ơn @Milimetric – Rich

+0

Điều này đã giải quyết cho tôi sau nhiều giờ không nhận được đâu !!! Nó sẽ được đánh dấu là câu trả lời! – Nick

1

Đây là cách đơn giản nhất tôi tìm thấy để làm điều đó, chỉ cần thêm các thuộc tính data-val-*-* trong HtmlAttributes của DropDownListFor, bên trong chế độ xem. Phương pháp sau đây cũng hoạt động với RemoteValidation, nếu bạn không cần xác thực từ xa, chỉ cần xóa các phần tử có chứa 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" } }) 

Tôi hy vọng nó có thể hữu ích. Trân trọng!

Các vấn đề liên quan