.NET WebApi如何防止"$ ref":"x" JSON的输出 [英] .NET WebApi How to prevent "$ref": "x" output of JSON

查看:115
本文介绍了.NET WebApi如何防止"$ ref":"x" JSON的输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将Web Api与Entity Framework一起使用,我有一个名为Gift的控制器,当客户端GET为API时,我将通过使用实体框架从DB获取所有Gifts并将其作为JSON返回

I'm Using Web Api with Entity Framework, I have a controller named as Gift, when client GET's the API I'm getting all Gifts from DB by using entity framework and and returning it as JSON

这是我的控制器功能

    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并哇哇我想要的还可以.

I can fix this problem by using a very mystic way; I'm adding a new blank line to web.config file and saving it, then I'm calling the API again and wholaa it is OK as I want.

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

But after 1-2 hours starting to send data with $ref until I add a new blank line to web.config file.

推荐答案

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

Json.net adds "$id" and "$ref" to serialized JSON to handle circular references. Your Gift object contains GiftCategory that in its turn contains list of Gift objects.

引用处理由PreserveReferencesHandling串行器设置控制,但是在具有循环引用的情况下,将SerializerSettings.PreserveReferencesHandling设置为PreserveReferencesHandling.None对您不起作用,因为这会导致数据丢失. Json.net足够聪明,不会让您用自己的腿射击.

Reference handling is controlled by PreserveReferencesHandling serializer setting, however setting SerializerSettings.PreserveReferencesHandling to PreserveReferencesHandling.None will not work for you in case of having circular references, because it will cause loosing of the data. Json.net is smart enough by not giving you shoot in own leg.

您可以尝试将ReferenceLoopHandling设置为ReferenceLoopHandling.Ignore,如出色的 answer 所述, 但是,由于特定的序列化顺序,Gift对象将在第一个参考位置进行序列化.因此,其中一些将进入Gifts数组,而其中一些将进入GiftCategory.有关更多详细信息,请参见此问题.

You could try to set ReferenceLoopHandling to ReferenceLoopHandling.Ignore as described in this great answer, however due to specific order of serialization, the Gift object will be serialized at first reference place. So some of them will get into Gifts array, and some of them will get into GiftCategory. See this question for more details.

所以可能的解决方法是:

So the possible fixes are:

  1. 首先,如建议的那样此处考虑不对EF实体进行序列化.

  1. At first, as suggested here consider not serializing EF entities.

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

If navigation property GiftCategory.Gifts isn't actually required by business logic of your application, you could delete it from the model entity. Then you will not have circular references anymore and serialized JSON will not have "$ref" and "$id" fields.

这篇关于.NET WebApi如何防止"$ ref":"x" JSON的输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆