Невозможно отобразить значения перечислимого числа в сетке Kendo

В моем приложении MVC5 у меня есть класс enum, как показано ниже, и с этим подходом я могу передать значения enum, а именно US, UK вместо United States "from Controller to View. Как передать и отобразить описание перечисления со следующим Я пробовал много разных методов решения как С# String enums и т.д., но ни одна из них не решила мою проблему. С другой стороны, я не хочу использовать закрытый класс и было бы лучше для меня решение с классом enum, как показано ниже:


Enum:

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");   

});

Ответ 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;
}

Ответ 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" },