c# - .NET WebApi如何防止 "$ref": "x" output of JSON

标签 c# asp.net json asp.net-web-api asp.net-web-api2

我将 Web Api 与 Entity Framework 一起使用,我有一个名为 Gift 的 Controller ,当客户端 GET 是 API 时,我通过使用 Entity Framework 从数据库中获取所有礼物并将其作为 JSON 返回

这是我的 Controller 函数

    public List<Gift> Get()
    {
        return GiftService.GetIncludeAndActive();
    }

这是服务函数

public List<Gift> GetIncludeAndActive()
{
    return dbSet.Include("GiftCategory").Where(x => x.Status == Model.Enums.GiftStatus.Active).OrderByDescending(x => x.Featured).ThenBy(x => x.Price).ToList();
}

这是礼物模型

public class Gift
    {
        public Gift()
        {
            this.CartItems = new List<CartItem>();
        }
        public int ID { get; set; }
        public string GiftName { get; set; }
        public string Image { get; set; }
        public int Stock { get; set; }
        public int Price { get; set; }
        public string Description { get; set; }
        public string Status { get; set; }
        public string GiftCode { get; set; }
        public int GiftCategoryID { get; set; }
        public Nullable<DateTime> CreatedAt { get; set; }
        public Nullable<DateTime> UpdatedAt { get; set; }
        public bool Featured { get; set; }
        public GiftCategory GiftCategory { get; set; }
        public ICollection<CartItem> CartItems { get; set; }

    }

[

这是 JSON 输出

{
        "$id": "1",
        "ID": 14,
        "GiftName": "Sinbo SVC-3438 1600 Watt Elektrikli Süpürge",
        "Image": "http://placehold.it/400x288.jpg/A6A",
        "Stock": 70,
        "Price": 260,
        "Description": "Az yer kaplayan Kompakt dizayn, Max. 1600W, 5m kablo uzunluğu, 360 derece dönüş açılı ön tekerlek, Dar ve ulaşılması zor yerler için 2 si 1 arada aparat ",
        "Status": "Active",
        "GiftCode": "BDRS-498",
        "GiftCategoryID": 4,
        "CreatedAt": "2016-12-19T12:59:01.31",
        "UpdatedAt": "2016-12-19T12:59:10.54",
        "Featured": false,
        "GiftCategory": {
          "$id": "2",
          "ID": 4,
          "Name": "Kişisel Bakım",
          "CountryID": 1,
          "Country": null,
          "Gifts": [
            {
              "$ref": "1"
            },
            {
              "$id": "3",
              "ID": 11,
              "GiftName": "Kişisel Bakım 2 - LG 43LH590V 43\"108 Ekran Full HD",
              "Image": "http://placehold.it/400x288.jpg/AEA",
              "Stock": 50,
              "Price": 3600,
              "Description": "Triple XD Engine teknolojisiyle güçlendirilen, Active Noise Reduction ve Real Cinema 24p özellikleriyle zenginleştirilen 1080p çözünürlüğündeki LED aydınlatmalı 55 inçlik ekrana sahip model, size ideal sinema keyfi sunuyor. Aynı zamanda sahip olduğu Color Prime, Dynamic Clear White ve Dynamic Colour Enhancer özellikleri sayesinde kusursuz bir görüntüyle evlerinizde yerini alıyor.",
              "Status": "Active",
              "GiftCode": "BDRS-495",
              "GiftCategoryID": 4,
              "CreatedAt": "2016-12-19T12:59:01.31",
              "UpdatedAt": "2016-12-19T12:59:10.54",
              "Featured": false,
              "GiftCategory": {
                "$ref": "2"
              },
              "CartItems": []
            },
            {
              "$id": "4",
              "ID": 8,
              "GiftName": "Kişisel Bakım 1 - Apple iPhone 6S 16 GB",
              "Image": "http://placehold.it/400x288.jpg/CCC",
              "Stock": 100,
              "Price": 5000,
              "Description": "Teknolojinin sunduğu tüm imkanlardan yararlanılarak tasarlanan Apple iPhone 6S , hem işlevsel hem de görsel açıdan ayrıcalıklı bir akıllı telefona sahip olmanıza olanak tanıyor.",
              "Status": "Active",
              "GiftCode": "BDRS-492",
              "GiftCategoryID": 4,
              "CreatedAt": "2016-12-19T12:59:01.31",
              "UpdatedAt": "2016-12-19T12:59:10.54",
              "Featured": false,
              "GiftCategory": {
                "$ref": "2"
              },
              "CartItems": []
            }
          ]
        },
        "CartItems": []
      },
      {
        "$id": "5",
        "ID": 13,
        "GiftName": "Beyaz Eşyalar 2 - Philips Marathon Ultimate FC9919/07 A Sınıfı Toz Torbasız Elektrikli Süpürge",
        "Image": "http://placehold.it/400x288.jpg/A1A",
        "Stock": 70,
        "Price": 900,
        "Description": "Yeni Philips Marathon Ultimate torbasız elektrikli süpürge, üstün temizlik performansı sunar. PowerCyclone 7, havayla tozu olağanüstü bir performansla ayırır. TriActiveMax başlık ise tüm zeminlerde mükemmel performans gösterir.",
        "Status": "Active",
        "GiftCode": "BDRS-497",
        "GiftCategoryID": 2,
        "CreatedAt": "2016-12-19T12:59:01.31",
        "UpdatedAt": "2016-12-19T12:59:10.54",
        "Featured": false,
        "GiftCategory": {
          "$id": "6",
          "ID": 2,
          "Name": "Beyaz Eşyalar",
          "CountryID": 1,
          "Country": null,
          "Gifts": [
            {
              "$ref": "5"
            },
            {
              "$id": "7",
              "ID": 6,
              "GiftName": "Beyaz Eşyalar 1 - Samsung Galaxy S7 Edge",
              "Image": "http://placehold.it/400x288.jpg/EEE",
              "Stock": 100,
              "Price": 6000,
              "Description": "Teknolojik yeniliklerin nereye kadar ulaşacağını kestiremeyen kullanıcılar, Samsung’un geliştirdiği ve bünyesinde barındırdığı yenilikçi özelliklerle öne çıkan telefonlarla şaşırmaya devam ediyor. Galaxy serisi içerisindeki en agresif atılımları üzerinde bulunduran Samsung Galaxy S7 Edge modelleri;alüminyum çerçeveleri, güçlü donanımları, benzersiz kameraları, suya ve toza karşı dayanıklılıkları ve sanal gerçeklik aygıtlarına doğrudan bağlanabilmeleriyle benzersiz hale geliyorlar.",
              "Status": "Active",
              "GiftCode": "BDRS-490",
              "GiftCategoryID": 2,
              "CreatedAt": "2016-12-19T12:59:01.31",
              "UpdatedAt": "2016-12-19T12:59:10.54",
              "Featured": false,
              "GiftCategory": {
                "$ref": "6"
              },
              "CartItems": []
            }
          ]
        },
        "CartItems": []
      },
      {
        "$id": "8",
        "ID": 7,
        "GiftName": "Elektronik 1 - Samsung Galaxy J7",
        "Image": "http://placehold.it/400x288.jpg/DDD",
        "Stock": 1000,
        "Price": 2500,
        "Description": "eknolojik yenilikleri yakından takip eden herkesin kullandığı akıllı cep telefonları, gelişmiş donanım ve yazılım özelliklerinin yanı sıra üzerlerinde bulunan kameralarla daha da kullanışlı hale geliyor. Dünya çapında milyonlarca kullanıcıya ulaşan ve akıllı cep telefonu sektörüne yön veren başlıca markalardan biri olan Samsung, Galaxy serisi içerisine konumlandırdığı Samsung Galaxy J7 modeliyle kendinden söz ettiriyor. ",
        "Status": "Active",
        "GiftCode": "BDRS-491",
        "GiftCategoryID": 3,
        "CreatedAt": "2016-12-19T12:59:01.31",
        "UpdatedAt": "2016-12-19T12:59:10.54",
        "Featured": false,
        "GiftCategory": {
          "$id": "9",
          "ID": 3,
          "Name": "Elektronik ",
          "CountryID": 1,
          "Country": null,
          "Gifts": [
            {
              "$ref": "8"
            },
            {
              "$id": "10",
              "ID": 12,
              "GiftName": "Elektronik  2 - Samsung 40JU6070 40\" 102 Ekran Ultra HD",
              "Image": "http://placehold.it/400x288.jpg/A6A",
              "Stock": 62,
              "Price": 3200,
              "Description": "TV standında kullanılabilen model, A enerji verimlilik sınıfında yer alıyor. Samsung 40JU6070 fiyatı kullanıcı açısından tercih edilir olmasında önemli bir rol oynuyor.4K teknolojisiyle yeni tanışacak olanların rahatlıkla yönelebilecekleri model, zengin giriş - çıkış noktalarıyla da cazip seçenekler arasında yer alıyor. Slim yapısı, pratik kullanımı ve gerek donanım gerekse yazılım anlamında Samsung’un elektronik alandaki deneyiminin bir eseri olarak nitelenebilecek akıllı televizyon, salon ya da oturma odalarınızın en sevilen eşyalarından biri oluyor.",
              "Status": "Active",
              "GiftCode": "BDRS-496",
              "GiftCategoryID": 3,
              "CreatedAt": "2016-12-19T12:59:01.31",
              "UpdatedAt": "2016-12-19T12:59:10.54",
              "Featured": false,
              "GiftCategory": {
                "$ref": "9"
              },
              "CartItems": []
            }
          ]
        },
        "CartItems": []
      },
      {
        "$id": "11",
        "ID": 9,
        "GiftName": "Küçük Ev Aletleri 1 - General Mobile 4G Android One",
        "Image": "http://placehold.it/400x288.jpg/BBB",
        "Stock": 150,
        "Price": 2600,
        "Description": "General Mobile 4G , diğer akıllı telefon modellerinden farklı olarak Google iş birliği ile geliştirilen Türkiye'deki ilk Android One cihaz olma özelliğine sahip ve bu yüzden benzeri bulunmayan eşsiz bir ürün.",
        "Status": "Active",
        "GiftCode": "BDRS-493",
        "GiftCategoryID": 5,
        "CreatedAt": "2016-12-19T12:59:01.31",
        "UpdatedAt": "2016-12-19T12:59:10.54",
        "Featured": false,
        "GiftCategory": {
          "$id": "12",
          "ID": 5,
          "Name": "Küçük Ev Aletleri",
          "CountryID": 1,
          "Country": null,
          "Gifts": [
            {
              "$ref": "11"
            }
          ]
        },
        "CartItems": []
      },
      {
        "$id": "13",
        "ID": 10,
        "GiftName": "Elektrikli Ev Aletleri 2 - Samsung 40J5070 40\" 102 Ekran Full HD",
        "Image": "http://placehold.it/400x288.jpg/AAA",
        "Stock": 50,
        "Price": 3000,
        "Description": "\r\nMarkaların ortaya koydukları televizyon modelleri, farklı donanım ve yazılım özellikleriyle öne çıkıyor. Gelişmiş 3D yetenekleri ve 4K çözünürlükleriyle sunulan bazı ürünler, sahip oldukları aygıttan çok sayıda özellik bekleyenlerin gereksinimlerini kolayca karşılıyor.",
        "Status": "Active",
        "GiftCode": "BDRS-494",
        "GiftCategoryID": 1,
        "CreatedAt": "2016-12-19T12:59:01.31",
        "UpdatedAt": "2016-12-19T12:59:10.54",
        "Featured": false,
        "GiftCategory": {
          "$id": "14",
          "ID": 1,
          "Name": "Elektrikli Ev Aletleri",
          "CountryID": 1,
          "Country": null,
          "Gifts": [
            {
              "$ref": "13"
            },
            {
              "$id": "15",
              "ID": 5,
              "GiftName": "Elektrikli Ev Aletleri 1 - Iphone 7 Plus 128GB",
              "Image": "http://placehold.it/400x288.jpg/FFF",
              "Stock": 200,
              "Price": 7500,
              "Description": "Apple markası iPhone serisi altında sunduğu cihazların arasına geçtiğimiz yıllarda Plus serisini de eklemişti. iPhone 7 cihazının yanı sıra sunulan iPhone 7 Plus , yüksek özellikleri ve normal iPhone’a göre büyük ekranı ile büyük ekran beklentisi olanların ihtiyacını karşılamayı hedefliyor.",
              "Status": "Active",
              "GiftCode": "BDRS-489",
              "GiftCategoryID": 1,
              "CreatedAt": "2016-12-19T12:59:01.31",
              "UpdatedAt": "2016-12-19T12:59:10.54",
              "Featured": false,
              "GiftCategory": {
                "$ref": "14"
              },
              "CartItems": []
            }
          ]
        },
        "CartItems": []
      },
      {
        "$ref": "10"
      },
      {
        "$ref": "3"
      },
      {
        "$ref": "4"
      },
      {
        "$ref": "7"
      },
      {
        "$ref": "15"
      }
    ]

如您所见,有 "$ref":"13"、"$ref":"14"等...我不想在 json 的底部显示 $refs,我不想要 $refs。我想要一个常规的 JSON 文件

这是我的 WebApiConfig.cs

     public static void Register(HttpConfiguration config)
        {

            config.SuppressDefaultHostAuthentication();
            config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
            config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
            config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.None;
.....

我可以通过一种非常神秘的方式解决这个问题;我在 web.config 文件中添加了一个新的空行并保存它,然后我再次调用 API 并 wholaa 它可以如我所愿。

但是在 1-2 小时后开始使用 $ref 发送数据,直到我向 web.config 文件添加一个新的空行。

最佳答案

Json.net 将 "$id""$ref" 添加到序列化的 JSON 中以处理循环引用。您的 Gift 对象包含 GiftCategory,后者又包含 Gift 对象列表。

引用处理由 PreserveReferencesHandling 序列化程序设置控制,但是将 SerializerSettings.PreserveReferencesHandling 设置为 PreserveReferencesHandling.None 将不起作用有循环引用,因为它会导致数据丢失。 Json.net 足够聪明,不会让你自取其辱。

您可以尝试将 ReferenceLoopHandling 设置为 ReferenceLoopHandling.Ignore,如这个伟大的 answer 中所述, 然而,由于序列化的特定顺序,Gift 对象将在第一个引用位置被序列化。所以它们中的一些会进入Gifts数组,一些会进入GiftCategory。看这个question了解更多详情。

所以可能的修复是:

  1. 一开始按照提示here考虑不序列化 EF 实体。

  2. 如果您的应用程序的业务逻辑实际上不需要导航属性 GiftCategory.Gifts,您可以将其从模型实体中删除。然后您将不再有循环引用,序列化的 JSON 将没有 "$ref""$id" 字段。

关于c# - .NET WebApi如何防止 "$ref": "x" output of JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41244296/

相关文章:

c# - 从区域调用 RenderPartial

c# - 在用户控件 asp.net 中声明事件?

c# - 在日历控件中自定义选择

c# - 替换由数字组成的子字符串

c# - 如何让代码契约相信变量不为空?

json - 如何在 delphi 中使用 THTTPClient 发布 json?

无法识别 Javascript 条件格式

javascript - Monaco 编辑器如何添加自定义语言解析器和语法验证

c# - 当前上下文中不存在名称 'controlname'

c# - ListView 在代码隐藏文件 aspx.cs 中检索值