2011-10-19 23 views
6

This Question es similar pero la respuesta aceptada lo resuelve del lado del servidor, estoy interesado en las soluciones del lado del cliente.DropDownListFor Unobtrusive Validación requerida No obtener los atributos correctos

Dado este modelo de vista

public class MyViewModel 
{ 
    public string ID { get; set; } 

    [Required(ErrorMessage = "I DEMAND YOU MAKE A CHOICE!")] 
    [Display(Name = "Some Choice")] 
    public int SomeChoice{ get; set; } 
    [Required(ErrorMessage = "I DEMAND YOU MAKE A CHOICE!")] 
    [Display(Name = "Keyword")] 
    public string Keyword { get; set; }  
} 

y la navaja

<div> 
@Html.LabelFor(model => model.SomeChoice, new { @class = "label" }) 
@Html.DropDownListFor(model => model.SomeChoice, (SelectList)ViewBag.SomeChoice, "Select...") 
@Html.ValidationMessageFor(model => model.SomeChoice) 
</div> 

y asumir ViewBag.SomeChoice contiene una lista de selección de opciones

El HTML representado no recibe los datos-val = "true" data-val-required = "¡DEMANDA QUE HACES UNA ELECCIÓN!" atributos como @ Html.EditorFor (model => model.Keyword) o @ Html.TextBoxFor representará.

¿POR QUÉ?

agregar una clase = "exigen" a ella al igual que

@Html.DropDownListFor(model => model.SomeChoice, (SelectList)ViewBag.SomeChoice, "Select...", new { @class = "required" }) 

que utiliza la semántica y los bloques de la clase de validación de jQuery en enviar, pero no muestra el mensaje. Puedo hacer este tipo de cosas

@Html.DropDownListFor(model => model.SomeChoice, (SelectList)ViewBag.SomeChoice, "Select...", new Dictionary<string, object> { { "data-val", "true" }, { "data-val-required", "I DEMAND YOU MAKE A CHOICE!" } }) 

que pondrá a la derecha atributos allí, y bloques de presentar y muestra el mensaje, pero no toma ventaja de la RequiredAttribute ErrorMessage que tengo en mi modelo de vista

Entonces, ¿alguien ha escrito una DropDownListFor que se comporte como los otros HtmlHelpers con respecto a la Validación?

EDITAR Aquí está mi código exacto

En HomeController.cs

public class MyViewModel 
    { 
    [Required(ErrorMessage = "I DEMAND YOU MAKE A CHOICE!")] 
    [Display(Name = "Some Choice")] 
    public int? SomeChoice { get; set; } 
    } 


    public ActionResult About() 
    { 
     var items = new[] { new SelectListItem { Text = "A", Value = "1" }, new SelectListItem { Text = "B", Value = "2" }, new SelectListItem { Text = "C", Value = "3" }, }; 
     ViewBag.SomeChoice = new SelectList(items,"Value", "Text"); 
     ViewData.Model = new MyViewModel {}; 
     return View(); 
    } 

About.cshtml

@using Arc.Portal.Web.Host.Controllers 
@model MyViewModel 
<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()) 
{ 
<div> 
    @Html.LabelFor(model => model.SomeChoice) 
    @Html.DropDownListFor(model => model.SomeChoice, (SelectList)ViewBag.SomeChoice, "Select...") 
    @Html.ValidationMessageFor(model => model.SomeChoice) 
</div> 

<button type="submit">OK</button> 
} 

Y aquí es el código rendido

<form action="/Home/About" method="post"> <div> 
    <label for="SomeChoice">Some Choice</label> 
    <select id="SomeChoice" name="SomeChoice"><option value="">Select...</option> 
<option value="1">A</option> 
<option value="2">B</option> 
<option value="3">C</option> 
</select> 
    <span class="field-validation-valid" data-valmsg-for="SomeChoice" data-valmsg-replace="true"> </span> 
</div> 
<button type="submit">OK</button> 
</form> 

Se publica de nuevo a mi controlador ... esto no debería ocurrir

Respuesta

5

utilizar simplemente un número entero anulable en la propiedad va a enlazar a la lista desplegable en su modelo de vista:

[Required(ErrorMessage = "I DEMAND YOU MAKE A CHOICE!")] 
[Display(Name = "Some Choice")] 
public int? SomeChoice { get; set; } 

También en para conseguir adecuado HTML5 discreta Data- * atribuye el menú desplegable debe estar dentro de un formulario:

@model MyViewModel 
<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()) 
{ 
    <div> 
     @Html.LabelFor(model => model.SomeChoice, new { @class = "label" }) 
     @Html.DropDownListFor(
      model => model.SomeChoice, 
      Model.ListOfChoices, 
      "Select..." 
     ) 
     @Html.ValidationMessageFor(model => model.SomeChoice) 
    </div> 

    <button type="submit">OK</button> 
} 

también se dará cuenta de que me deshice de ViewBag (que simplemente los cc ot stand) y lo reemplazó con una propiedad correspondiente en su modelo de vista que contendrá las opciones posibles para el menú desplegable.

+3

Realicé la nullable y todavía no se pueden escribir los elementos de validación de datos en el control – Peter

3

Tuve el mismo problema.Y notó que esto sucede cuando dropDownList se llena desde ViewBag o ViewData. Si escribiera @ Html.DropDownListFor (modelo => modelo.SomeChoice, Model.SomeChoice, "Seleccionar ...") como en el ejemplo anterior, se escribirían los atributos de validación.

+1

Eso es decepcionante en el extremo. Extraigo toda mi lista de selección del modelo en 'ViewData', por lo que a la lista se puede acceder mediante un nombre de lista en un atributo' UIHIn't based. – ProfK

+0

Información decepcionante, pero útil para saber. Lamentablemente, el mundo real rara vez tiene que estar siempre fuertemente tipado. – ItinerantEngineer

0

Aquellos que están aquí buscando el mismo comportamiento en la lista desplegable de Kendo, agregue 'requerido' en su código.

@(Html.Kendo().DropDownListFor(m => m) 
    .Name("FeatureId").BindTo((System.Collections.IEnumerable)ViewData[CompanyViewDataKey.Features]) 
    .DataValueField("Id") 
    .DataTextField("Name") 
    .OptionLabel("--Select--") 
    .HtmlAttributes(new { title="Select Feature", required="required"}) 

)

[Obligatorio] atributo en el modelo de vista no funcionó para mí, pero añadiendo lo anterior en htmlAttributes hizo. Espero que esto ayude a alguien.

Cuestiones relacionadas