【问题标题】:How to reduce code duplication in ASP.NET MVC view when working with Flags enum使用 Flags 枚举时如何减少 ASP.NET MVC 视图中的代码重复
【发布时间】:2016-06-23 11:49:44
【问题描述】:

原谅我的无知。没有做很多 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 中的相关概念是什么?

【问题讨论】:

  • 谷歌搜索给了我this;不确定它是否正是您需要的,但应该让您了解需要做什么
  • bool IsFoobool IsBarbool IsMeh创建一个视图模型然后你可以使用强类型Html.CheckBoxFor()方法来生成复选框

标签: c# asp.net-mvc enums enum-flags


【解决方案1】:

当您提交表单时,您当前的代码不会绑定到您的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)
....

最后在 POST 方法中

[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

【讨论】:

    【解决方案2】:

    创建剃刀助手:

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

    或共享视图

    【讨论】:

    • 或者在视图模型中使用@Html.CheckBoxFor 是的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多