2011-10-19 15 views
6

This Question è simile ma la risposta accettata risolve il problema lato server, sono interessato alle soluzioni lato client.DropDownListFor Convalida non richiesta Richiesto Non ottenere gli attributi corretti

Dato questo ViewModel

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

e il rasoio

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

e assumere ViewBag.SomeChoice contiene un elenco selezionato di scelte

il codice HTML reso non ottiene il data-val = "true" data-val-required = "I DEMAND YOU MAKE A CHOICE!" attributi come @ Html.EditorFor (model => model.Keyword) o @ Html.TextBoxFor eseguono il rendering.

PERCHÉ?

Aggiunta di un class = "necessaria" ad esso in questo modo

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

che utilizza la semantica di classe jQuery convalida e blocchi su presentare, ma non visualizza il messaggio. Posso fare questo genere di cose

@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!" } }) 

che metterà il diritto attributi lì, e blocca il presentare e mostra il messaggio, ma non approfitta del RequiredAttribute ErrorMessage che ho sul mio ViewModel

Quindi qualcuno ha scritto un DropDownListFor che si comporta come gli altri HtmlHelpers per quanto riguarda la validazione?

EDIT Ecco il mio codice esatto

In 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> 
} 

E qui è il codice di reso

<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> 

il postback al mio controller ... questo non dovrebbe accadere

risposta

5

è sufficiente utilizzare un intero annullabile sulla proprietà si sono vincolanti per la DropDownList del modello di visualizzazione:

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

Anche in fine di ottenere una corretta discreto HTML5 dati- * attribuisce la discesa deve essere all'interno di un modulo:

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

Inoltre si noterà che mi sono liberato di ViewBag (che ho semplicemente cann ot stand) e lo ha sostituito con una proprietà corrispondente sul tuo modello di vista che conterrà le possibili scelte per il menu a discesa.

+3

Ho fatto l'int nullable e non riesce ancora a scrivere gli elementi di convalida dei dati nel controllo – Peter

3

Ho avuto lo stesso problema.E ha notato che ciò accade quando dropDownList viene popolato da ViewBag o ViewData. Se dovessi scrivere @ Html.DropDownListFor (model => model.SomeChoice, Model.SomeChoice, "Select ...") come sopra, gli attributi di convalida di esempio verrebbero scritti.

+1

Ciò è deludente all'estremo. Estraggo tutta la mia lista di selezione dal modello in 'ViewData' in modo che la lista sia accessibile da un nome di lista in un attributo' UIHIn't. – ProfK

+0

Informazioni deludenti, ma utili da sapere. Purtroppo il mondo reale raramente viene sempre fortemente tipizzato. – ItinerantEngineer

0

Quelli che stanno cercando lo stesso comportamento nell'elenco a discesa Kendo, si prega di aggiungere 'richiesto' nel codice.

@(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"}) 

)

[Required] attributo nel ViewModel non ha funzionato per me, ma l'aggiunta di quanto sopra in Htmlattributes ha fatto. Spero che questo aiuti qualcuno.

Problemi correlati