.NET WebApi如何防止"$ ref":JSON的"x"输出

fob*_*bus 3 c# asp.net json asp.net-web-api asp.net-web-api2

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

这是我的控制器功能

    public List<Gift> Get()
    {
        return GiftService.GetIncludeAndActive();
    }
Run Code Online (Sandbox Code Playgroud)

这是服务功能

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();
}
Run Code Online (Sandbox Code Playgroud)

这是礼物模特

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

    }

[
Run Code Online (Sandbox Code Playgroud)

这是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"
      }
    ]
Run Code Online (Sandbox Code Playgroud)

你可以看到有"$ ref":"13","$ ref":"14"等...我不想在json的底部显示$ 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;
.....
Run Code Online (Sandbox Code Playgroud)

我可以用一种非常神秘的方式解决这个问题; 我正在为web.config文件添加一个新的空白行并保存它,然后我再次调用API,然后根据我的需要调用它.

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

Cod*_*ler 9

Json.net添加"$id""$ref"序列化JSON来处理循环引用.您的Gift对象包含的对象包含对象GiftCategory列表Gift.

参考处理由控制PreserveReferencesHandling串行器的设定,但是设定SerializerSettings.PreserveReferencesHandlingPreserveReferencesHandling.None不会有循环引用的情况下,为你工作,因为它会导致数据丢失的.Json.net通过不给你自己的腿射击是足够聪明的.

你可以尝试设置ReferenceLoopHandlingReferenceLoopHandling.Ignore在这个伟大的描述答案,但是由于串行化的具体顺序,Gift对象将首先参考的地方被序列化.因此,他们中的一些人将进入Gifts阵列,其中一些将进入GiftCategory.有关详细信息,请参阅此问题.

所以可能的修复方法是:

  1. 首先,正如这里建议的那样,考虑不要序列化EF实体.

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