2013-03-12 2 views
9

Мне трудно понять, как преобразовать значение Enum в соответствующее имя. Моя модель выглядит следующим образом:Получение перечисления для отображения на стороне клиента

public class CatalogRule 
{ 
    public int ID { get; set; } 
    [Display(Name = "Catalog"), Required] 
    public int CatalogID { get; set; } 
    [Display(Name = "Item Rule"), Required] 
    public ItemType ItemRule { get; set; } 
    public string Items { get; set; } 
    [Display(Name = "Price Rule"), Required] 
    public PriceType PriceRule { get; set; } 
    [Display(Name = "Value"), Column(TypeName = "MONEY")] 
    public decimal PriceValue { get; set; } 
    [Display(Name = "Exclusive?")] 
    public bool Exclude { get; set; } 
} 

public enum ItemType 
{ 
    Catalog, 
    Category, 
    Group, 
    Item 
} 

public enum PriceType 
{ 
    Catalog, 
    Price_A, 
    Price_B, 
    Price_C 
} 

Результат выборки из .net API:

[ 
    { 
    $id: "1", 
    $type: "XYZ.CMgr.Models.CatalogRule, XYZ.CMgr", 
    ID: 1, 
    CatalogID: 501981, 
    ItemRule: 0, 
    Items: "198", 
    PriceRule: 1, 
    PriceValue: 0.5, 
    Exclude: false 
    }, 
    { 
    $id: "2", 
    $type: "XYZ.CMgr.Models.CatalogRule, XYZ.CMgr", 
    ID: 2, 
    CatalogID: 501981, 
    ItemRule: 2, 
    Items: "9899", 
    PriceRule: 2, 
    PriceValue: 10.45, 
    Exclude: false 
    } 
] 

Таким образом, в этом примере, мне нужно получить Каталог результатов [0] .ItemRule & Цена A для результатов [0] .PriceRule. Как я могу это сделать в BreezeJS?

ответ

4

Там будет новый релиз в ближайшие несколько дней, когда мы «меняем» поведение переименования бриза (т. е. нарушаем существующий код в отношении перечислений). В новой версии перечисления сериализуются и запрашиваются их именами .NET, а не целыми числами. Я отправлю сообщение здесь, когда выйдет новый релиз.

+0

При исследовании этой проблемы я обнаружил, что, хотя метаданные Enum присутствовали в вызове API/метаданных, он был отброшен на стороне клиента Breeze. Спасибо за обновление Jay. –

+1

Breeze v 1.2.1 был только что выпущен, и перечисления теперь можно запросить как строки и материализоваться таким образом. –

+0

Кстати, я обновил несколько минут назад тоже ...;) Эта версия решает проблему, Thanx ... –

7

Это легко сделать в ASP.NET Web API, потому что это встроенная функция в сериализаторе JSON по умолчанию (Json.NET).

Чтобы увидеть строки вместо чисел перечислений в JSON, просто добавьте экземпляр StringEnumConverter к настройкам Serializer JSON во время приложения INIT:

var jsonFormatter = GlobalConfiguration.Configuration.Formatters.JsonFormatter; 
jsonFormatter.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter()); 

UPDATE: Да, вы правы, это не поможет с Breeze .js. Хорошо, вы все равно можете сделать небольшое волшебство, чтобы enums работали как строки (в то время как новая версия с исправлением не была выпущена).

Создайте пользовательский ContextProvider, который обновляет все значения перечисления целого числа в метаданных для строк. Вот оно:

public class StringEnumEFContextProvider<T> : EFContextProvider<T> 
    where T : class, new() 
{ 
    protected override string BuildJsonMetadata() 
    { 
     XDocument xDoc; 
     if (Context is DbContext) 
     { 
      xDoc = GetCsdlFromDbContext(Context); 
     } 
     else 
     { 
      xDoc = GetCsdlFromObjectContext(Context); 
     } 

     var schemaNs = "http://schemas.microsoft.com/ado/2009/11/edm"; 

     foreach (var enumType in xDoc.Descendants(XName.Get("EnumType", schemaNs))) 
     { 
      foreach (var member in enumType.Elements(XName.Get("Member", schemaNs))) 
      { 
       member.Attribute("Value").Value = member.Attribute("Name").Value; 
      } 
     } 

     return CsdlToJson(xDoc); 
    } 
} 

И использовать его вместо EFContextProvider в контроллерах Web API:

private EFContextProvider<BreezeSampleContext> _contextProvider = 
     new StringEnumEFContextProvider<BreezeSampleContext>(); 

Это хорошо работает для меня с текущей версией Breeze.js (1.1.3), хотя я гавань «т проверяются другие сценарии, как проверка ...

UPDATE:. Чтобы исправить проверки, тип данных изменений для перечислений в бризе [мин | Debug] .js, вручную (DataType.fromEdmDataType функцию, dt = DataType.String; для е Num) или заменить функцию по умолчанию во время приложения INIT:

breeze.DataType.fromEdmDataType = function (typeName) { 
    var dt = null; 
    var parts = typeName.split("."); 
    if (parts.length > 1) { 
     var simpleName = parts[1]; 
     if (simpleName === "image") { 
      // hack 
      dt = DataType.Byte; 
     } else if (parts.length == 2) { 
      dt = DataType.fromName(simpleName); 
      if (!dt) { 
       if (simpleName === "DateTimeOffset") { 
        dt = DataType.DateTime; 
       } else { 
        dt = DataType.Undefined; 
       } 
      } 
     } else { 
      // enum 
      dt = DataType.String; // THIS IS A FIX! 
     } 
    } 

    return dt; 
}; 

Грязные, грязные хаки, я знаю ... Но это решение, которое я нашел

+0

Я боюсь, что это не повлияло на обратный вызов API. Это может быть связано с тем, что контроллер Breeze обрабатывает вызовы API и такие ... –

+0

@Van Dame, я обновил ответ с помощью решения для текущей версии Breeze.js – whyleee

+0

Спасибо за исправления, но кажется, что это исправление не понадобится в несколько дней, и я предпочел бы избежать хаков ... :) –

Смежные вопросы