2013-03-12 19 views
9

Ich habe Schwierigkeiten zu verstehen, wie Sie einen Enum-Wert in den entsprechenden Namen konvertieren. Mein Modell ist wie folgt:Abrufen einer Enum auf Clientseite

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 
} 

Eine Probe resultiert aus .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 
    } 
] 

So in diesem Beispiel, ich brauche Katalog erhalten für Ergebnisse [0] .ItemRule & Preis A für Ergebnisse [0] .PriceRule. Wie kann ich das in BreezeJS erreichen?

Antwort

4

Es wird eine neue Version heraus in den nächsten Tagen, wo Wir ändern das Enumerationsverhalten von Breeze (dh brechen bestehenden Code in Bezug auf Enums). In der neuen Version werden Enums serialisiert und mit ihren .NET-Namen anstatt als Ganzzahlen abgefragt. Ich werde hier zurück posten, wenn die neue Version veröffentlicht wird.

+0

Bei der Untersuchung dieses Problems habe ich festgestellt, dass Enum-Metadaten zwar im API-Aufruf "/ Metadata" vorhanden waren, aber auf der Clientseite von Breeze verworfen wurden. Danke für das Update Jay. –

+1

Breeze v 1.2.1 wurde gerade veröffentlicht und enums können jetzt als Strings abgefragt werden und werden auch auf diese Weise materialisiert. –

+0

Übrigens habe ich vor ein paar Minuten auch aktualisiert ...;) Diese Version löst das Problem, Danke ... –

7

Dies ist in der ASP.NET-Web-API einfach durchzuführen, da es sich um eine Standardfunktion im standardmäßigen JSON-Serializer (Json.NET) handelt.

Um Strings statt Enum Zahlen in JSON zu sehen, nur eine Instanz von StringEnumConverter zu JSON Serializer Einstellungen während der app init hinzufügen:

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

UPDATE: Ja, du hast recht, das mit Breeze helfen nicht .js. Ok, du kannst trotzdem ein bisschen Magie machen, um Enums wie Strings arbeiten zu lassen (während eine neue Version mit Fix nicht veröffentlicht wird).

Erstellen Sie eine benutzerdefinierte ContextProvider, die alle Integer Enum-Werte in Metadaten zu Zeichenfolgen aktualisiert. Hier ist sie:

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

Und es anstelle von EFContextProvider in Ihrem Web-API-Controller:

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

Dies funktioniert gut für mich mit aktueller Breeze.js Version (1.1.3), obwohl ich haven ‚t überprüft andere Szenarien, wie die Validierung ...

UPDATE:. beheben Validierung, Datenänderungstyp für Aufzählungen in Brise [min | debug] Js, manuell (DataType.fromEdmDataType Funktion, dt = DataType.String; für e num) oder Standard-Funktion während der App init ersetzen:

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; 
}; 

Schmutzig, schmutzig Hacks, ich weiß ... Aber das ist die Lösung, die ich

gefunden
+0

Ich fürchte, das hatte keine Auswirkungen auf den API-Rückruf. Das kann daran liegen, dass der Breeze-Controller die API-Aufrufe verarbeitet und so ... –

+0

@VanDame, ich habe die Antwort mit der aktuellen Breeze.js-Version aktualisiert – whyleee

+0

Danke für die Korrekturen, aber es scheint, dass diese Korrektur nicht notwendig sein wird ein paar Tage und ich würde lieber keine Hacks vermeiden ... :) –

Verwandte Themen