问题
Forgive my ignorance. Not done a lot of MVC work, and I'm sure there must be a better way to do this but I can't seem to find it. I have a Flags enum like this:
[Flags]
public enum Services
{
Foo = 1,
Bar = 2,
Meh = 4
}
And a SelectedServices property on my Model which has a value of this type. In the View, I have a checkbox for each possible service. I have implemented the binding logic like so:
<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>
And so on. Which works, but is really horribly messy.
There must, surely be a better way to encapsulate this - but I have no idea what the relevant concept is in MVC?
回答1:
Create razor helper :
@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)
or shared view
回答2:
You current code would not bind to your enum
when you submit the form since it will only be received as an array of values. As always, use a view model to represent what you want to display/edit in a view.
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
}
and to map the enum
value to the view model
model.IsFoo= yourEnumProperty.HasFlag(Type.Foo); // etc
and in the view
@model MyViewModel
....
@Html.CheckBoxFor(m => m.IsFoo)
@Html.LabelFor(m => m.IsFoo)
@Html.CheckBoxFor(m => m.IsBar)
@Html.LabelFor(m => m.IsBar)
....
and finally in the POST method
[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
来源:https://stackoverflow.com/questions/37990786/how-to-reduce-code-duplication-in-asp-net-mvc-view-when-working-with-flags-enum