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

2 回答 2

7

这在 ASP.NET Web API 中很容易做到,因为它是默认 JSON 序列化程序 (Json.NET) 中的一个开箱即用功能。

StringEnumConverter要在 JSON 中查看字符串而不是枚举数字,只需在应用程序初始化期间向 JSON 序列化程序设置添加一个实例:

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

更新:是的,你说得对,这对 Breeze.js 没有帮助。好的,无论如何,您都可以做一些魔术来使枚举像字符串一样工作(而未发布带有修复的新版本)。

创建一个自定义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),虽然我没有检查其他场景,比如验证......

更新:要修复验证,请在微风中更改枚举的数据类型。[min|debug].js,手动(DataType.fromEdmDataType函数,dt = DataType.String;用于枚举)或在应用程序初始化期间替换默认函数:

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

肮脏,肮脏的黑客,我知道......但这就是我找到的解决方案

于 2013-03-12T22:48:25.520 回答
4

在接下来的几天里将发布一个新版本,我们“改变”微风的枚举行为(即打破现有的关于枚举的代码)。在新版本中,枚举通过它们的 .NET 名称而不是整数进行序列化和查询。当新版本发布时,我会在这里发布。

于 2013-03-13T18:58:05.133 回答