在使用标志枚举时,如何减少ASP.NET MVC视图中的代码重复



原谅我的无知。没有做很多MVC工作,我敢肯定必须有更好的方法来做到这一点,但我似乎找不到。我有这样的标志:

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

和我的模型上具有此类值的SelectedServices属性。在视图中,我为每个可能的服务都有一个复选框。我已经实现了绑定逻辑:

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

等等。有效,但真的很混乱。

必须有一种更好的方法来封装这一点 - 但我不知道MVC中的相关概念是什么?

当您提交表单时,当前代码将不会绑定到您的enum,因为仅作为值数组收到。与往常一样,使用视图模型表示您要在视图中显示/编辑的内容。

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
}

并将enum值映射到视图模型

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

和视图

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

,最后在邮政方法

[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

创建剃须刀助手:

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

或共享视图

最新更新