C# 在HTML.enumdopdownlistfor中添加自定义值

C# 在HTML.enumdopdownlistfor中添加自定义值,c#,asp.net,asp.net-mvc,html-helper,C#,Asp.net,Asp.net Mvc,Html Helper,到目前为止,我有过这样的经历: public enum MyEnum { [Display(Name="FirstElement")] element1 = 1, [Display(Name="SecondElement")] element2 = 2 } public enum MyEnum { [Display(Name="FirstElement")] element1 = 1, [Display(Name="SecondEleme

到目前为止,我有过这样的经历:

public enum MyEnum
{
    [Display(Name="FirstElement")]
    element1 = 1,
    [Display(Name="SecondElement")]
    element2 = 2
}
public enum MyEnum
{
    [Display(Name="FirstElement")]
    element1 = 1,
    [Display(Name="SecondElement")]
    element2 = 2,
    [Display(Name="Third")]
    element-dashed = 3
}
在视图中,如果我使用:

Html.EnumDropDownListFor(x=>x.EnumProperty)
同时:

public MyEnum EnumProperty {get;set;}
在视图模型上,下拉菜单按预期工作(我看到
FirstElement
,附加的值是
element1

问题是我想在值中加一个破折号,如下所示:

public enum MyEnum
{
    [Display(Name="FirstElement")]
    element1 = 1,
    [Display(Name="SecondElement")]
    element2 = 2
}
public enum MyEnum
{
    [Display(Name="FirstElement")]
    element1 = 1,
    [Display(Name="SecondElement")]
    element2 = 2,
    [Display(Name="Third")]
    element-dashed = 3
}
它将不起作用,因为元素虚线不是有效的条目。 这也行不通:

[Value("element-dashed")]
[Display(Name="Third")]
elementDashed = 3

你问题的答案很简单。但这需要一个解释,来解释为什么这是答案

在枚举中没有需要破折号的功能原因。

假设我有一个工作应用程序,其中包含您的枚举:

public enum MyEnum
{
    [Display(Name="FirstElement")]
    element1 = 1,
    [Display(Name="SecondElement")]
    element2 = 2
}
假设我更改了枚举数名称:

public enum MyEnum
{
    [Display(Name="FirstElement")]
    BatmanIsBruceWayne = 1,
    [Display(Name="SecondElement")]
    SupermanIsClarkKent = 2
}
我假设代码中枚举的每个用法都会相应地进行调整。如果在VS(F2)中使用重命名方法,则会自动出现这种情况

应用程序的工作方式没有任何变化。从功能上讲,枚举的名称并不重要

public enum CardSuit { Hearts, Spades, Diamonds, Clubs }

public enum CardSuit { TheRedOne, TheBlackOne, TheOtherRedOne, TheOtherBlackOne }
当然,对于开发人员来说,第一个版本比第二个版本更具可读性。但是,编译器并不关心枚举名称的含义。它只关心一致地使用适当的值

这与变量名的原理相同。当然,我们应该注意让开发人员能够阅读变量名;在
int x
上使用
int myDescriptiveInteger
没有任何技术原因(即应用程序的功能性原因)。
我们仅为维护代码的人员的可读性选择描述性名称


只有一个例外情况:如果您在枚举上调用
.ToString()
,以获得所使用字段的字符串表示形式

注:虽然这在技术上是可行的,并且其他人以前也做过;我真不知道你是否真的应该在这里这么做。您已经在为枚举值指定显式int值。保存/加载枚举时,这些int值比使用其等效字符串容易得多。虽然这两种方法在技术上都是可行的,但是使用int要好得多,因为它占用的空间更小,并且没有您错误地试图在这里修复的命名问题

从你的问题中不清楚你的情况是否如此。也许它是在你的应用程序中完成的,也许不是。你不告诉我我就不知道了

如果不执行,则您的问题与功能无关。除了可读性之外,名称并不重要,我确信您的开发人员不会因为缺少破折号而突然停止理解代码的意图

如果完成了,那么您实际上已经提供了问题的答案。而不是在枚举上调用
.ToString()
;相反,您必须使用
[Display(Name=“FirstElement”)]
的值作为枚举的正确“字符串名”

public static string GetName(this myEnum enumValue)
{
    return enumValue.GetType()
                    .GetMember(enumValue.ToString())
                    .GetCustomAttribute<DisplayAttribute>()
                    .GetName();
}
以下代码正确使用属性值而不是枚举字段名:

myEnumValue.GetName();
在这两种情况下,核心答案都是一样的:您不必担心枚举字段的特定名称,因为它在功能上是不相关的

public static string GetName(this myEnum enumValue)
{
    return enumValue.GetType()
                    .GetMember(enumValue.ToString())
                    .GetCustomAttribute<DisplayAttribute>()
                    .GetName();
}

编辑如果希望枚举值在组合框中的显示方式与保存值时的显示方式不同,请使用第二个属性来区分两者。但原则仍然是:不要以枚举使用的字段名为基础


我想再次强调,您应该使用枚举的整数值。我看不出有什么理由明确地将int值分配给枚举,然后拒绝使用它们。

我认为您混淆了什么是代码/数据,什么是UI。仅仅因为C#允许在UI中使用这些奇特的东西,并不意味着代码支持它(例如,变量或带有破折号的类型)。为什么您想要一个带有破折号的变量(此时变量/枚举是数据,而不是UI中的某些内容)我没有混淆它们,我知道代码不支持变量中的破折号,这就是问题的原因。但要求/要求我在保存时在值中加一个破折号,并且要求来自非技术人员。在保存时,我曾考虑在某种映射器中用“element-smash”替换“element-smash”,但如果可能的话,我正在寻找更好的方法。我猜想,在某个时候,该值将写入数据库,或导出到其他“外部”系统?只需在那里执行所需的格式设置。是的,可能需要执行类似的操作,只是没有想到这会是干净的代码,或者我将手动填充SelectList属性并使用DropdownListFor而不是EnumDropdownListFor。无论如何,谢谢你,我没有必要使用字段名,这就是为什么我尝试使用Value属性,以及为什么标题显示customvalue。在我看来,扩展方法确实是最好的,它使用了[Value]属性,因为我希望[Display]属性保持独立,因为它有不同的含义。