Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/30.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 带有整数字符串的枚举_C#_Asp.net_Asp.net Mvc - Fatal编程技术网

C# 带有整数字符串的枚举

C# 带有整数字符串的枚举,c#,asp.net,asp.net-mvc,C#,Asp.net,Asp.net Mvc,我有一个公共的enum如下: public enum occupancyTimeline { TwelveMonths, FourteenMonths, SixteenMonths, EighteenMonths } 我将使用它作为下拉菜单,如下所示: @Html.DropDownListFor(model => model.occupancyTimeline, new SelectList(Enum.GetValues(typeof(Centra

我有一个公共的
enum
如下:

public enum occupancyTimeline
{
    TwelveMonths,
    FourteenMonths,
    SixteenMonths,
    EighteenMonths
}
我将使用它作为
下拉菜单,如下所示:

@Html.DropDownListFor(model => model.occupancyTimeline, 
   new SelectList(Enum.GetValues(typeof(CentralParkLCPreview.Models.occupancyTimeline))), "")
现在我正在寻找这样的价值观

12个月、14个月、16个月、18个月,而不是二十个月、十四个月、十六个月、十八个月

我将如何做到这一点

public enum occupancyTimeline
{
    TwelveMonths=0,
    FourteenMonths=1,
    SixteenMonths=2,
    EighteenMonths=3
}
public string[] enumString = {
    "12 Months", "14 Months", "16 Months", "18 Months"};

string selectedEnum = enumString[(int)occupancyTimeLine.TwelveMonths];


我为自己制作了一种扩展方法,现在我在每个项目中都使用这种方法:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Web.Mvc;

namespace App.Extensions
{
    public static class EnumExtensions
    {
        public static SelectList ToSelectList(Type enumType)
        {
            return new SelectList(ToSelectListItems(enumType));
        }

        public static List<SelectListItem> ToSelectListItems(Type enumType, Func<object, bool> itemSelectedAction = null)
        {
            var arr = Enum.GetValues(enumType);
            return (from object item in arr
                    select new SelectListItem
                    {
                        Text = ((Enum)item).GetDescriptionEx(typeof(MyResources)),
                        Value = ((int)item).ToString(),
                        Selected = itemSelectedAction != null && itemSelectedAction(item)
                    }).ToList();
        }

        public static string GetDescriptionEx(this Enum @this)
        {
            return GetDescriptionEx(@this, null);
        }

        public static string GetDescriptionEx(this Enum @this, Type resObjectType)
        {
            // If no DescriptionAttribute is present, set string with following name
            // "Enum_<EnumType>_<EnumValue>" to be the default value.
            // Could also make some code to load value from resource.

            var defaultResult = $"Enum_{@this.GetType().Name}_{@this}";

            var fi = @this.GetType().GetField(@this.ToString());
            if (fi == null)
                return defaultResult;

            var customAttributes = fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
            if (customAttributes.Length <= 0 || customAttributes.IsNot<DescriptionAttribute[]>())
            {
                if (resObjectType == null)
                    return defaultResult;

                var res = GetFromResource(defaultResult, resObjectType);
                return res ?? defaultResult;
            }

            var attributes = (DescriptionAttribute[])customAttributes;
            var result = attributes.Length > 0 ? attributes[0].Description : defaultResult;
            return result ?? defaultResult;
        }

        public static string GetFromResource(string defaultResult, Type resObjectType)
        {
            var searchingPropName = defaultResult;
            var props = resObjectType.GetProperties();
            var prop = props.FirstOrDefault(t => t.Name.Equals(searchingPropName, StringComparison.InvariantCultureIgnoreCase));
            if (prop == null)
                return defaultResult;
            var res = prop.GetValue(resObjectType) as string;
            return res;
        }

        public static bool IsNot<T>(this object @this)
        {
            return !(@this is T);
        }
    }
}
更新

根据Phil的建议,我已经更新了上面的代码,可以从一些资源(如果您有)中读取enum的显示值。资源中项目的名称应采用
Enum\uuuu
的形式(例如
Enum\u occumencytimeline\u十二个月
)。通过这种方式,您可以在资源文件中为枚举值提供文本,而无需使用某些属性修饰枚举值。资源类型(MyResource)直接包含在ToSelectItems方法中。您可以将其提取为扩展方法的参数

命名枚举值的另一种方法是应用Description属性(这种方法不需要使代码适应我所做的更改)。例如:

public enum occupancyTimeline
{
    [Description("12 Months")]
    TwelveMonths,
    [Description("14 Months")]
    FourteenMonths,
    [Description("16 Months")]
    SixteenMonths,
    [Description("18 Months")]
    EighteenMonths
}

对枚举进行扩展描述

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.ComponentModel;
public static class EnumerationExtensions
{
//This procedure gets the <Description> attribute of an enum constant, if any.
//Otherwise, it gets the string name of then enum member.
[Extension()]
public static string Description(Enum EnumConstant)
{
    Reflection.FieldInfo fi = EnumConstant.GetType().GetField(EnumConstant.ToString());
    DescriptionAttribute[] attr = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
    if (attr.Length > 0) {
        return attr(0).Description;
    } else {
        return EnumConstant.ToString();
    }
}

}
使用系统;
使用系统集合;
使用System.Collections.Generic;
使用系统数据;
使用系统诊断;
使用System.Runtime.CompilerServices;
使用系统组件模型;
公共静态类枚举扩展
{
//此过程获取枚举常量(如果有)的属性。
//否则,它将获取枚举成员的字符串名称。
[扩展名()]
公共静态字符串描述(枚举常量)
{
Reflection.FieldInfo fi=EnumConstant.GetType().GetField(EnumConstant.ToString());
DescriptionAttribute[]attr=(DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute),false);
如果(属性长度>0){
返回属性(0)。说明;
}否则{
返回EnumConstant.ToString();
}
}
}

除了使用属性进行描述(请参阅其他答案或使用谷歌),我经常使用RESX文件,其中键是枚举文本(例如,
十二个月
),值是所需的文本

然后,执行一个返回所需文本的函数是相对简单的,而且为多语言应用程序翻译值也很容易

我还想添加一些单元测试,以确保所有值都有关联的文本。如果有一些异常(比如最后的
Count
值),那么单元测试将从检查中排除这些异常

所有这些都不是很难,也不是很灵活。如果您使用
DescriptionAttribute
并希望获得多语言支持,那么您仍然需要使用资源文件

通常,我会有一个类来获取每个
enum
类型需要显示的值(显示的名称),每个资源文件有一个单元测试文件,尽管我还有一些其他类用于一些常见代码,比如比较资源文件中的键和单元测试的
enum
中的值(一个重载允许指定异常)

顺便说一句,在这种情况下,让
枚举的值与月数匹配(例如
twevemonths=12
)是有意义的。在这种情况下,您还可以使用
string.Format
来显示值,并且资源中也有异常(如单数).

您可以用于此目的。以下是您想要的示例。(不要忘记使用
EnumDropDownList for
您应该使用ASP MVC 5和Visual Studio 2015。):

你的看法:

@using System.Web.Mvc.Html
@using WebApplication2.Models
@model WebApplication2.Models.MyClass

@{
    ViewBag.Title = "Index";
}

@Html.EnumDropDownListFor(model => model.occupancyTimeline)
还有你的模特:

public enum occupancyTimeline
{
    [Display(Name = "12 months")]
    TwelveMonths,
    [Display(Name = "14 months")]
    FourteenMonths,
    [Display(Name = "16 months")]
    SixteenMonths,
    [Display(Name = "18 months")]
    EighteenMonths
}

参考资料:MVC 5.1

@Html.EnumDropDownListFor(model => model.MyEnum)
MVC 5

@Html.DropDownList("MyType", 
   EnumHelper.GetSelectList(typeof(MyType)) , 
   "Select My Type", 
   new { @class = "form-control" })
MVC 4

你可以参考这个链接

用法

你可以看看这个

他的解决方案是针对Asp.NET的,但是通过简单的修改,你可以像MVC一样使用它

/// <span class="code-SummaryComment"><summary></span>
/// Provides a description for an enumerated type.
/// <span class="code-SummaryComment"></summary></span>
[AttributeUsage(AttributeTargets.Enum | AttributeTargets.Field, 
 AllowMultiple = false)]
public sealed class EnumDescriptionAttribute :  Attribute
{
   private string description;

   /// <span class="code-SummaryComment"><summary></span>
   /// Gets the description stored in this attribute.
   /// <span class="code-SummaryComment"></summary></span>
   /// <span class="code-SummaryComment"><value>The description stored in the attribute.</value></span>
   public string Description
   {
      get
      {
         return this.description;
      }
   }

   /// <span class="code-SummaryComment"><summary></span>
   /// Initializes a new instance of the
   /// <span class="code-SummaryComment"><see cref="EnumDescriptionAttribute"/> class.</span>
   /// <span class="code-SummaryComment"></summary></span>
   /// <span class="code-SummaryComment"><param name="description">The description to store in this attribute.</span>
   /// <span class="code-SummaryComment"></param></span>
   public EnumDescriptionAttribute(string description)
       : base()
   {
       this.description = description;
   }
}
您可以在控制器中使用它来填充下拉列表,如下所示:

ViewBag.occupancyTimeline =new SelectList( EnumHelper.ToList(typeof(occupancyTimeline)),"Value","Key");
在您看来,您可以使用以下

@Html.DropdownList("occupancyTimeline")

希望它能帮助您发布解决方案的模板,您可以根据需要更改某些部分

定义用于格式化枚举的通用EnumHelper:

public abstract class EnumHelper<T> where T : struct
{
    static T[] _valuesCache = (T[])Enum.GetValues(typeof(T));

    public virtual string GetEnumName()
    {
        return GetType().Name;
    }

    public static T[] GetValuesS()
    {
        return _valuesCache;
    }

    public T[] GetValues()
    {
        return _valuesCache;
    }      

    virtual public string EnumToString(T value)
    {
        return value.ToString();
    }                
}

我会选择一种稍有不同且可能更简单的方法:

public static List<int> PermittedMonths = new List<int>{12, 14, 16, 18};

以您描述的方式使用枚举可能有点麻烦。

您可以将getter强制转换为整数,而不是尝试从
枚举
在视图中绘制属性。我的问题是,我将枚举的值编写为字符串,但我希望使用它的int值

例如,在视图模型类中可以有以下两个属性:

public enum SomeEnum
{
   Test = 0,
   Test1 = 1,
   Test2,
}

public SomeEnum SomeEnum {get; init;}

public int SomeEnumId => (int) SomeEnum;
然后,您可以通过razor
视图访问您的
enum
,如下所示:

<input type="hidden" asp-for="@Model.SomeEntityId" />


您的意思是显示在您的下拉菜单中?显示在下拉菜单中并作为其值。幸运的是,没有设置枚举
.ToString()
函数的事情,我相信。您有没有看过这个问题?我会用
字典替换您的
字符串[]
枚举字符串:更易于维护(例如,如果您将枚举定义移动到另一个文件中)对我来说,这似乎是一个很好的答案,但缺少一些关键信息。如何指定与枚举值关联的自定义文本?更新了我的答案。希望能有所帮助。我收到了一个错误,它是
var defaultResult=$“enum{@this.GetType().Name}{@this}”
$”字符串插值是在C#6.0(Visual studio 2015)中首次引入的。如果它不起作用,您可以使用string.Format。鉴于问题是在C#中提出的,您应该在C#中回答,或者至少告诉我们它是VB.NET,可以(轻松)转换,以便我们知道您知道。我得到一个错误…
@Html.DropDownListFor(model=>model.OccupncyTimeLine,model.OccupncyTimeLine.ToSelectList());
:“string”不包含“ToSelectList”的定义,并且没有扩展方法“ToSelectList”接受第一个
ViewBag.occupancyTimeline =new SelectList( EnumHelper.ToList(typeof(occupancyTimeline)),"Value","Key");
@Html.DropdownList("occupancyTimeline")
public abstract class EnumHelper<T> where T : struct
{
    static T[] _valuesCache = (T[])Enum.GetValues(typeof(T));

    public virtual string GetEnumName()
    {
        return GetType().Name;
    }

    public static T[] GetValuesS()
    {
        return _valuesCache;
    }

    public T[] GetValues()
    {
        return _valuesCache;
    }      

    virtual public string EnumToString(T value)
    {
        return value.ToString();
    }                
}
public static class SystemExt
{
    public static MvcHtmlString DropDownListT<T>(this HtmlHelper htmlHelper,
        string name,
        EnumHelper<T> enumHelper,
        string value = null,
        string nonSelected = null,
        IDictionary<string, object> htmlAttributes = null)
        where T : struct
    {
        List<SelectListItem> items = new List<SelectListItem>();

        if (nonSelected != null)
        {
            items.Add(new SelectListItem()
            {
                Text = nonSelected,
                Selected = string.IsNullOrEmpty(value),
            });
        }

        foreach (T item in enumHelper.GetValues())
        {
            if (enumHelper.EnumToIndex(item) >= 0)
                items.Add(new SelectListItem()
                {
                    Text = enumHelper.EnumToString(item),
                    Value = item.ToString(),                 //enumHelper.Unbox(item).ToString()
                    Selected = value == item.ToString(),
                });
        }

        return htmlHelper.DropDownList(name, items, htmlAttributes);
    }
}
public class OccupancyTimelineHelper : EnumHelper<OccupancyTimeline>
{
    public override string EnumToString(occupancyTimeline value)
    {
        switch (value)
        {
            case OccupancyTimelineHelper.TwelveMonths:
                return "12 Month";
            case OccupancyTimelineHelper.FourteenMonths:
                return "14 Month";
            case OccupancyTimelineHelper.SixteenMonths:
                return "16 Month";
            case OccupancyTimelineHelper.EighteenMonths:
                return "18 Month";
            default:
                return base.EnumToString(value);
        }
    }
}
@Html.DropDownListT("occupancyTimeline", new OccupancyTimelineHelper())
public static List<int> PermittedMonths = new List<int>{12, 14, 16, 18};
foreach(var permittedMonth in PermittedMonths)
{
    MyDropDownList.Items.Add(permittedMonth.ToString(), permittedMonth + " months");
}
public enum SomeEnum
{
   Test = 0,
   Test1 = 1,
   Test2,
}

public SomeEnum SomeEnum {get; init;}

public int SomeEnumId => (int) SomeEnum;
<input type="hidden" asp-for="@Model.SomeEntityId" />