无法在 Kendo 网格上显示枚举值

Posted

技术标签:

【中文标题】无法在 Kendo 网格上显示枚举值【英文标题】:Cannot display enum values on Kendo grid 【发布时间】:2016-03-21 11:51:35 【问题描述】:

在我的 MVC5 应用程序中,我有一个枚举类,如下所示,通过这种方法,我可以将枚举值(即美国、英国而不是美国)从 Controller 传递到 View。如何通过以下方式传递和显示枚举描述方法?我尝试了许多不同的解决方法,如C# String enums 等,但没有一个能解决我的问题。另一方面,我不想使用密封类,对我来说,使用枚举类的解决方案会更好,如图所示下面:

枚举:

public enum Country

    [Description("United States")]
    US = 1,
    [Description("United Kingdom")]
    UK = 2,
    [Description("New Zealand")]
    NewZealand = 3,
    [Description("France")]
    France = 4,
    [Description("Germany")]
    Germany = 5

型号:

public class VisitorViewModel

    [Key]
    public int VisitorID  get; set; 

    public Country Country  get ; set; 
    //code omitted for brevity

控制器:

public JsonResult Visitor_Read([DataSourceRequest] DataSourceRequest request)

    var result = db.Visitors.Select(m => new VisitorViewModel
    
        VisitorID = m.VisitorID,
        Country = m.Country
        //code omitted for brevity
    )      
    var jsonResult = Json(result, JsonRequestBehavior.AllowGet);
    jsonResult.MaxJsonLength = int.MaxValue;
    return jsonResult;

查看:

$(document).ready(function () 

    var grid = $("#visitorGrid").kendoGrid(            
        dataSource: 
            type: "json",
            transport: 
                read: 
                    url: "/Visitor/Visitor_Read",
                    dataType: "json",
                    cache: false
                
            ,
            schema: 
                model: 
                    fields: 
                        VisitorID:  type: 'number' ,
                        Country :  type: 'string' 
                    
                
            
        ,
        columns:
        [   
             field: "VisitorID", title: "Id" ,
             field: "Country ", title: "Country" , 
        ]
    ).data("kendoGrid");   

);

【问题讨论】:

如果您使用的是 asp.net MVC,为什么不使用 razor 创建网格? 您可以添加额外的getter public string CountryName,返回Country.ToString() @ataravati 我用的是razor(查看页面是cshtml)。如果你是说 Kendo MVC,我以前用过,但在这个项目中,出于某种原因,我不得不在 javascript 中使用 Kendo Grid。另一方面,解决这个问题有意义吗?因为首先我需要将由多个单词组成的字符串值从控制器返回到视图。至少对此有任何想法吗? @GeneR 但是我使用 EF Code First 方法,我不确定向相关实体类添加新属性是否会导致数据库中出现额外的列。我应该将它用作虚拟吗?您可以通过更改我的原始代码来发布示例吗? @Christof 我首先使用 EF 逆向工程代码,并为模型生成 partial class,然后为模型自定义属性创建相同的 partial class 【参考方案1】:

您必须为自定义属性设置NotMapped 属性:

using System.ComponentModel.DataAnnotations.Schema;
public class VisitorViewModel

    [Key]
    public int VisitorID  get; set; 

    public Country Country  get; set; 

    [NotMapped]
    public string CountryName
    
        get  return Country.GetDescription(); 
    

GetDescription() 是下一个扩展方法:

public static string GetDescription(this Enum e)

    var field = e.ToString();
    var attribute = e.GetType().GetField(field).GetCustomAttributes(typeof(DescriptionAttribute), false).FirstOrDefault();

    return attribute != null ? ((DescriptionAttribute)attribute).Description : field;

【讨论】:

完美且非常简单...非常感谢 Gene,现在它就像一个魅力 :) 已投票+【参考方案2】:

您必须创建将返回描述属性的方法。它可以是一些辅助方法、扩展或任何你想要的。

例如:

public class VisitorViewModel

    [Key]
    public int VisitorID  get; set; 

    public Country Country  get ; set; 
    //code omitted for brevity

    public  string GetDescription()
    
        var type = typeof(Country);
        var memInfo = type.GetMember(this.Country.ToString());
        var attributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
        return ((DescriptionAttribute)attributes[0]).Description;
    

所以你可以这样称呼它

var result = db.Visitors.Select(m => new VisitorViewModel

    VisitorID = m.VisitorID,
    Country = m.GetDescription()
    //code omitted for brevity
)  

或者,如果它对你更好,创建将被类似调用的辅助方法,但将是静态的......

public class SomeHelperClass

    public static string GetDescription(VisitorViewModel model)
    
        var type = typeof(Country);
        var memInfo = type.GetMember(model.Country.ToString());
        var attributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
        return ((DescriptionAttribute)attributes[0]).Description;
    

所以调用看起来像

SomeHelperClass.GetDescription(model);

编辑 我有一个想法,也许它不是你想要的,也许它可以帮助你。 如果您添加带有国家名称的属性,您也可以使用此方法:

public class VisitorViewModel

    [Key]
    public int VisitorID  get; set; 

    public string CountryName  get; set; 

    private Country _country;
    public Country Country 
     
        get  return this._country; 
        set
        
            this._country = value;
            this.CountryName = GetDescription(value);
        
    
    //code omitted for brevity

    private string GetDescription(Country country)
    
        var type = typeof(Country);
        var memInfo = type.GetMember(country.ToString());
        var attributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
        return ((DescriptionAttribute)attributes[0]).Description;
    

所以如果你像你一样填充你的模型

var result = db.Visitors.Select(m => new VisitorViewModel

    VisitorID = m.VisitorID,
    Country = m.Country
    //code omitted for brevity
)    

您将自动填写可在剑道网格中使用的 CountryName 属性。

 field: "CountryName", title: "Country" , 

【讨论】:

非常感谢您的回复。我尝试了第一种和第二种方法,但得到以下错误:对于第一种方法,我得到“LINQ to Entities 无法识别方法 'System.String GetDescription()' 方法,并且此方法无法转换为存储表达式。”我查看了解决方法,但没有解决问题。第二次我得到“支持'DbContext'上下文的模型自数据库创建以来已经改变。”错误。我知道这不是错误,但表明迁移和更新数据库会导致数据库中出现我不想要的额外冒号(CountryName)。 @Christof 您可以对 CountryName 列使用 NotMapped 属性。 link我忘记了.. 非常感谢 Ademar,但由于 Gene 之前使用“NotMapped”发布了工作代码,我选择了他的答案。但当然投票+你的答案。再次非常感谢:)

以上是关于无法在 Kendo 网格上显示枚举值的主要内容,如果未能解决你的问题,请参考以下文章

具有可编辑枚举列的 Kendo MVC 网格

如何在网格行中显示枚举描述或名称?

Kendo grid getKendoGrid无法使用扩展的kendo网格

Kendo UI:将网格摘要值放在页脚中

为啥除非手动更改页面大小,否则 Kendo Grid 无法正确显示数据?

Kendo网格过滤无法正常工作