2012-03-24 3 views
0

Lasst uns sagen, dass Sie eine Enumeration wie dieses:Benutzerdefinierte Validierungsserver und Client-Seite für eine Dropdownlist mit Aufzählungstyp bevölkert

public enum ColorsEnum 
{ 
    Undefined, 
    Blue, 
    Red, 
    Green 
} 

Und ein Modell wie folgt aus:

public class Foo 
{ 
    public ColorsEnum PreferedColor { get; set; } 
} 

Mit Blick wie diese :

@model WebUI.Models.Foo 

@using (Html.BeginForm()) 
{ 
    @Html.LabelFor(m => m.PreferedColor) 
    @Html.DropDownListForEnum(m => m.PreferedColor) 
    <input type="submit"> 
} 

Hier ist der Helfer für die DropdownListForEnum:

public static IHtmlString DropDownListForEnum<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, 
                    Expression<Func<TModel, TProperty>> expression) 
    { 
     var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); 
     if (metaData.ModelType.IsEnum) 
     { 
      var names = Enum.GetNames(metaData.ModelType); 
      var translatedNames = GetTranslatedNames(metaData.ModelType); 

      var query = from p in names 
         select new SelectListItem 
            { 
             Text = translatedNames.ContainsKey(p) ? translatedNames[p] : p, 
             Value = p, 
             Selected = false 
            }; 

      return htmlHelper.DropDownList(metaData.PropertyName, query.ToList()); 
     } 
     else 
     { 
      throw new ApplicationException(
       "The DropDownListForEnum helper function must be used with an enum property"); 
     } 
    } 

Meine Frage: wie Sie die Validierung durchführen kann (Client & Server-Seite) eine gültige Farbe sicher sein durch den Benutzer choosed ist? 'Nicht definierte' Farbe sollte durch den Validierungsprozess abgelehnt werden.

Danke.

Antwort

0

würde ich ein Nullable-Enum und ein erforderliches Attribut auf dem View-Modell verwenden:

public class MyViewModel 
{ 
    [Required] 
    public ColorsEnum? PreferedColor { get; set; } 
} 

So könnte man den Undefined Wert von Ihrem Enumerationsdefinition entfernen:

public enum ColorsEnum 
{ 
    Blue, 
    Red, 
    Green 
} 

und dann etwas ändern Helfer:

public static class HtmlExtensions 
{ 
    public static IHtmlString DropDownListForEnum<TModel, TProperty>(
     this HtmlHelper<TModel> htmlHelper, 
     Expression<Func<TModel, TProperty>> expression 
    ) 
    { 
     var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); 
     var enumType = Nullable.GetUnderlyingType(metaData.ModelType); 
     if (enumType == null || !enumType.IsEnum) 
     { 
      throw new ApplicationException(
       "The DropDownListForEnum helper function must be used with a nullable enum property" 
      ); 
     } 

     var names = Enum.GetNames(enumType); 
     var translatedNames = GetTranslatedNames(metaData.ModelType); 

     var query = 
      from p in names 
      select new SelectListItem 
      { 
       Text = translatedNames.ContainsKey(p) ? translatedNames[p] : p, 
       Value = p, 
       Selected = false 
      }; 
     return htmlHelper.DropDownList(
      metaData.PropertyName, 
      query.ToList(), 
      "-- Select a color --" 
     ); 
    } 
} 

und dann eine einfache Kontrolle haben ler zu testen:

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

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

und eine entsprechende Ansicht:

@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()) 
{ 
    @Html.LabelFor(m => m.PreferedColor) 
    @Html.DropDownListForEnum(m => m.PreferedColor) 
    <input type="submit" /> 
} 
+0

Thant ist viel klarer für mich. Vielen Dank. – Bronzato

0

Wenn der erste Wert jedes Enum Sie mit DropDownListForEnum zur Verwendung planen ist immer eine „default“ Option, die vom Prüfer abgelehnt werden sollte, könnten Sie erwägen den Einsatz von optionLabel Parametern von DropDownList machen.

Setzen Sie das erste Element aus query und übergeben Sie diese Zeichenfolge als dritten Parameter in DropDownList.

return htmlHelper.DropDownList(metaData.PropertyName, query.ToList(), 
    /* some string containing default value extracted from your enum */); 

Auf diese Weise alle DropDownListForEnum erstellt DDLs verwendet, wird der erste Wert der Enumeration als „default“ Wert verwenden, und alles, was Sie zu bestätigen tun müsste, ist eine [Required] Datenaufbelichtung zu PreferredColor hinzuzufügen.

Alternativ können Sie die Option Default von Ihrem Enum entfernen und lassen Sie Ihren Htmlhelper (oder eine neue erstellen) einen dritten Parameter zu nehmen, eine Zeichenfolge, die die optionLabel enthält, die Sie DropDownList passieren würde.

Wie auch immer, die Idee ist, optionLabel zu verwenden, da der Validator die ganze Arbeit für Sie erledigen wird.

+0

Ihnen sehr danken. Es macht mehr Sinn, optionLabel zu verwenden. Also habe ich meinen ersten Wert in enum (Undefined) entfernt und ein optionLabel verwendet. Aber wenn die Ansicht generiert wird, ist die OptionLabel ("Bitte auswählen ...") nicht ausgewählt, dies ist immer der erste Eintrag in meiner Enum ?? irgendeine Idee? – Bronzato

+0

Ich denke, das könnte daran liegen, dass die DDL an PreferredColor gebunden ist und der Standardwert von PreferredColor nach dem Entfernen von Default blau wird. Ich bin vertrauter mit DDLs, die an Ints gebunden sind, also habe ich das nicht berücksichtigt. Eine Alternative könnte darin bestehen, Default in Ihrer Enumeration zu belassen, aber in DropDownListForEnum einen Bool-Parameter zu verwenden, der Ihrem HtmlHelper mitteilt, ob der erste Wert als optionLabel extrahiert werden soll oder nicht. Auf diese Weise können Sie sie für alle Enums verwenden, unabhängig davon, ob die Standardoption in der Enumeration enthalten ist. – nightshifted

+0

@nightshifted Eine Alternative könnte eine Zeichenfolge [] excludeList zu den Parametern hinzufügen, so dass Sie optional alle Elemente der Enumeration ausschließen können. Würde das gleiche Endergebnis aber etwas mehr Flexibilität bieten? – dreza

Verwandte Themen