【问题标题】:ASP.NET MVC Where to keep the values for SelectListsASP.NET MVC 在哪里保存 SelectLists 的值
【发布时间】:2012-01-11 19:26:27
【问题描述】:

目前,我的 ViewModel 顶部出现了所有这些混乱,我觉得这违反了 DTO 的目的。例如,这是在我的一个视图模型的构造函数中 -

        Dictionary<int, string> chargeGroups = new Dictionary<int, string>();
        chargeGroups.Add(1, "Administration");
        chargeGroups.Add(2, "Annual Leave");
        chargeGroups.Add(3, "Bereavement");
        chargeGroups.Add(4, "Customer Installation, Setup & Training");
        chargeGroups.Add(5, "Customer Support");
        chargeGroups.Add(6, "Internal Training & Education");
        chargeGroups.Add(7, "Sales & Marketing");
        chargeGroups.Add(8, "Sick");
        chargeGroups.Add(9, "Software Devel / Maint / Test");
        chargeGroups.Add(10, "Software Upgrade / Patch");
        chargeGroups.Add(11, "Other");
        chargeGroups.Add(12, "Other Absence");
        chargeGroups.Add(13, "Warranty");
        chargeGroups.Add(14, "Public Holiday");
        chargeGroups.Add(15, "Other Paid Leave");

        ChargeGroups = new SelectList(chargeGroups, "Key", "Value");

我的视图模型:

    [DisplayName("Charge group")]
    public short? ChargeGroup { get; set; }

    public SelectList ChargeGroups;

那么在我看来:

            <div class="editor-label">
                @Html.LabelFor(model => model.ChargeGroup)
            </div>
            <div class="editor-field">
                @Html.DropDownListFor(model => model.ChargeGroup, Model.ChargeGroups)
                @Html.ValidationMessageFor(model => model.ChargeGroup)
            </div>

我应该把这些东西放在哪里?

【问题讨论】:

  • 好吧,因为这是一个 ViewModel 而不是一个模型,我在这里没有看到问题。这与渲染视图有关,因此在 ViewModel 中是有意义的。在回发时,我会将其转换为模型,然后再发送到数据库,这样您就不会违反 DTO……无论如何,我对其他人对此的看法很感兴趣。
  • 我同意@JohnKalberer。 ViewModel 不必是完全贫乏的 DTO,它可以包含与 View 相关的逻辑。我将在控制器中(或由控制器使用)将传入的 ViewModel 数据转换为 Model 业务层,并返回到传出的 ViewModel 数据。 (附注:为什么在业务模型上有SelectListSelectList 不是专门的 MVC UI 元素吗?业务模型不应该与 UI 实现紧密耦合。)
  • 我的意思是说 ViewModel 不是模型对不起。 [已编辑]

标签: c# asp.net-mvc entity-framework


【解决方案1】:

当我有一个不会更改的值列表时,我通常使用枚举,然后使用自定义 Html 帮助器来呈现选择列表。您可以使用元数据描述标记自定义枚举值的显示文本。

这样你就可以使用:

 <%: Html.EnumDropDownListFor(model => model.EnuProperty) %>

 @Html.EnumDropDownListFor(model => model.EnuProperty)

查看 Simon 的这篇文章,它允许您使用 Meta Description 属性来自定义 Enum 名称的输出:

How do you create a dropdownlist from an enum in ASP.NET MVC?

这是另一个示例,但它缺少元描述属性:

http://blogs.msdn.com/b/stuartleeks/archive/2010/05/21/asp-net-mvc-creating-a-dropdownlist-helper-for-enums.aspx

编辑

你的枚举可能看起来像这样

 public enum ChargeGroupEnum
 {
    [Description("Administration")]
    Administration=1,
    [Description("Annual Leave")]
    AnnualLeave=2,
    [Description("Bereavement")]
    Bereavement=3,
    [Description("Customer Installation, Setup & Training")]
    CustomerInstallation=4,
    [Description("Customer Support")]
    CustomerSupport=5,
    [Description("Internal Training & Education")]
    InternalTraining=6,
    [Description("Sales & Marketing")]
    SalesMarketing=7,
    [Description("Sick")]
    Sick=8,
    [Description("Software Devel / Maint / Test")]
    Development=9,
    [Description("Software Upgrade / Patch")]
    Upgrade=10,
    [Description("Other")]
    Other=11,
    [Description("Other Absence")]
    OtherAbsence=12,
    [Description("Warranty")]
    Warranty=13,
    [Description("Public Holiday")]
    PublicHoliday=14,
    [Description(")ther Paid Leave")]
    OtherPaidLeave=15
}

然后在您的视图模型上,您可以使用以下内容使该字段以无值开头并需要一个值:

 [Required(ErrorMessage=" * required")]
 public ChargeGroupEnum? ChargeGroup {get;set;}

然后在您看来,您将使用 Html 助手“ChargeGroupEnum”,您需要从我链接到的帖子中获取它。

 @Html.EnumDropDownListFor(model => Model.ChargeGroup) 

如果你的模型有一个 Int,你可以很容易地从 Enum => Int 和 Int => Enum 开始。

【讨论】:

  • 我已更新示例以包含如何从 Razor 调用 Html Helper。逻辑不会改变,您可以像使用 MVC 中的任何其他辅助方法(Html、Url 等)一样使用它。
  • 有趣的方法。枚举是否存储在 Viewmodel 上?
  • 如果枚举列表需要从数据库表中加载怎么办?
  • @NoPyGod 枚举可以存储在 ViewModel 或 Model 或一个通用类中。位置无所谓。您必须在视图模型中创建一个枚举类型的属性。
  • @NickW 如果您的列表是数据库驱动的并且您使用 INT 值作为您的属性,例如“ChargeGroupID”,您可以创建一个 Html Helper,从数据库中加载可用选项列表,缓存它们到一个静态列表,然后根据结果创建一个选择列表。
【解决方案2】:

我认为在从数据源加载数据后缓存该数据并通过辅助方法基于该数据呈现控件将是一个更好的解决方案。

【讨论】:

  • 它不是从数据源加载的,它只是一个值数组。我主要关心的是我在哪里保存值数组?在 ViewModel 上,在控制器上? Viewbag..等
  • 这就是为什么我说从数据源加载它,导致该列表中的每个更改都需要重新编译,重新部署,并且没有意义,即使您可以将其保存在资源或 xml 文件中
【解决方案3】:

我决定将选择列表的值保留在另一个名为 OtherData 的类中,该类位于我的模型文件中的主 DBContext 类旁边。

【讨论】:

    【解决方案4】:

    与视图模型相比,在视图中创建 SelectList 不是更理想,这样视图模型就不会与视图对象 (SelectList) 紧密耦合吗?

    我知道视图模型用于视图,因此将它们紧密耦合会更好,但理论上如果视图被替换为不使用 SelectList 的东西,如果没有,您可以重用更多视图模型' t 使用该 SelectList。

    【讨论】:

      【解决方案5】:
      public static List<string> PaymentCurrency = new List<string> { "USD", "GBP", "EUR", "AUD", "BRL", "CAD", "CHF", "CLP", "CNY", "CZK", "DKK", "FJD", "HKD", "HNL", "HUF", "IDR", "ILS", "INR", "ISK", "JPY", "KRW", "LVL", "MXN", "MYR", "NOK", "NZD", "PHP", "PKR", "PLN", "RUB", "SEK", "SGD", "THB", "TRY", "TWD", "ZAR" };
      
      List<SelectListItem> PaymentCurrencyOptionItems = new List<SelectListItem>() { new SelectListItem { Text = "", Value = "" } };
          PaymentCurrencyOptionItems.AddRange(Lolio.PaymentCurrency.Select(r => new SelectListItem { Text = r+" "+LangResources.Get("Currency_" + r), Value = r }));
      
      IEnumerable<SelectListItem> LinkPaymentType = new SelectList(PaymentTypeOptionItems, "Value", "Text", lnk.Performance.PaymentType);
      
      Html.DropDownListFor(m => m.PaymentType, LinkPaymentType))
      

      【讨论】:

      • 这不是很有帮助,你根本没有回答我的问题。
      猜你喜欢
      • 1970-01-01
      • 2019-05-22
      • 2010-11-13
      • 2016-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-03
      • 2019-01-19
      相关资源
      最近更新 更多