2016-06-23 12 views
2

Verzeihen Sie meine Ignoranz. Nicht viel MVC-Arbeit gemacht, und ich bin mir sicher, dass es eine bessere Möglichkeit geben muss, dies zu tun, aber ich kann es nicht finden. Ich habe einen Flags wie dieser Enum:So reduzieren Sie Code-Duplizierung in ASP.NET MVC-Ansicht beim Arbeiten mit Flags enum

[Flags] 
public enum Services 
{ 
    Foo = 1, 
    Bar = 2, 
    Meh = 4 
} 

Und eine SelectedServices Eigenschaft auf meinem Modell, das einen Wert dieses Typs hat. In der Ansicht habe ich ein Kontrollkästchen für jeden möglichen Service. Ich habe die Binding-Logik wie folgt implementiert:

<div><label><input type="checkbox" name="services" value="@((int)Services.Foo)" 
@if(Model.SelectedServices.HasFlag(Services.Foo)) 
{ 
    <text>checked</text> 
} 
/>Foo</label></div> 

<div><label><input type="checkbox" name="services" value="@((int)Services.Bar)" 
@if(Model.SelectedServices.HasFlag(Services.Bar)) 
{ 
    <text>checked</text> 
} 
/>Bar</label></div> 

Und so weiter. Was funktioniert, ist aber wirklich schrecklich chaotisch.

Es muss sicherlich eine bessere Möglichkeit geben, dies zu kapseln - aber ich habe keine Ahnung, was das relevante Konzept in MVC ist?

+0

Google-Suche ergab zur Karte ich [dies] (http: // stackov erflow.com/questions/388483/how-do-you-create-a-dropdownlist-from-an-enum-in-asp-net-mvc); nicht sicher, ob es genau das ist, was Sie brauchen, aber sollte Ihnen eine Vorstellung davon geben, was Sie tun müssen –

+0

Erstellen Sie ein Ansichtsmodell mit 'bool IsFoo' und' bool IsBar' und 'bool IsMeh', dann können Sie das stark typisierte' Html verwenden .CheckBoxFor() 'Methode zum Erzeugen der Checkboxen –

Antwort

2

erstellen Rasierer Helfer:

@helper DisplayFlagHelper(Services flag) 
{ 
    <div><label><input type="checkbox" name="services" value="@((int)flag)" 
    if(Model.SelectedServices.HasFlag(flag)) 
    { 
     <text>checked</text> 
    } 
    />@flag</label></div> 
} 

@DisplayFlagHelper (Services.Foo)

oder geteilte Ansicht

+0

Oder verwenden Sie @ Html.CheckBoxFor mit View Model yes. – borgez

4

Sie aktuelle Code nicht auf Ihre enum binden, wenn Sie das Formular abschicken, da es wird nur als ein Array von Werten erhalten werden. Verwenden Sie wie immer ein Ansichtsmodell, um darzustellen, was Sie in einer Ansicht anzeigen/bearbeiten möchten.

public class MyViewModel 
{ 
    [Display(Name = "Foo")] 
    public bool IsFoo { get; set; } 
    [Display(Name = "Bar")] 
    public bool IsBar { get; set; } 
    [Display(Name = "Meh")] 
    public bool IsMeh { get; set; } 
    .... // other properties of your view model 
} 

und den enum Wert auf die Ansicht Modell

model.IsFoo= yourEnumProperty.HasFlag(Type.Foo); // etc 

und in der Ansicht

@model MyViewModel 
.... 
@Html.CheckBoxFor(m => m.IsFoo) 
@Html.LabelFor(m => m.IsFoo) 
@Html.CheckBoxFor(m => m.IsBar) 
@Html.LabelFor(m => m.IsBar) 
.... 

und schließlich in der POST-Methode

[HttpPost] 
public ActionResult Edit(MyViewModel model) 
{ 
    bool isTypeValid = model.IsFoo || model.IsBar || model.IsMeh; 
    if (!isTypeValid) 
    { 
     // add a ModelState error and return the view 
    } 
    Services myEnumValue = model.IsFoo ? Services.Foo : 0; 
    myEnumValue |= model.IsBar ? Services.Bar : 0; 
    myEnumValue |= model.IsMeh ? Services.Meh : 0; 
    // map the view model to an instance of the data model, save and redirect