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

したがって、この例では、 results[0].ItemRule のCatalogと results[0].PriceRuleの Price Aを取得する必要があります。BreezeJSでこれを達成するにはどうすればよいですか??

4

2 に答える 2

7

これは、既定の JSON シリアライザー (Json.NET) の既定の機能であるため、ASP.NET Web API で簡単に実行できます。

StringEnumConverterJSON で列挙型番号の代わりに文字列を表示するには、アプリの初期化中に 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);
    }
}

Web API コントローラーの代わりに使用EFContextProviderします。

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

これは、現在の Breeze.js バージョン (1.1.3) でうまく機能しますが、検証などの他のシナリオは確認していません...

更新:検証を修正するには、breast.[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 に答える