2016-12-20 50 views
0

一個小前奏ASP.NET WebApi - 兩種可能的JSON「返回」類型?

您好,我開發的WebAPI REST服務,目前我正在返回不同的字典端點在JSON(實體的陣列,不Dictionary數據類型混淆)格式。字典可以按名稱檢索:/dictionaries/:dictName。問題是,物品存放在字典可以有兩種類型:

第一類實體

class Item { 
    public long ID { get; set; } 
    public string Name { get; set; } 
} 

第二類實體的 - 擴展項

class ExtendedItem : Item { 
    public string AdditionalProperty { get; set; } // Let's name it this way just for example 
} 

問題

我想避免發送不需要它的字典AdditionalProperty


目前的解決方案

我已經開發了一個ApiController簡單的方法:

public IHttpActionResult GetDict(string name) 
{ 
    try 
    { 
     object outDict = null; 

     switch(name) { 
      case "simpleDict": 
       IList<Item> simpleDict = _dataLayer.GetSimpleDict(); 
       // ... 
       outDict = simpleDict; 
       break; 
      case "extDict": 
       IList<ExtendedItem> extDict = _dataLayer.GetExtDict(); 
       // ... 
       outDict = extDict; 
       break; 

      // ... and a few more dictionaries 
     } 

     SomeLogger.SomeLogging(name, outDict); 
     return Ok(outDict); 
    } 
    catch (Exception ex) 
    { 
     // Just returning error 
     return BadRequest(ex.Message); 
    } 

} 

結論和問題

雖然我設法找到這個問題的解決方案,我並不完全滿意。就個人而言,我想找一個簡單的方法來避免使用object數據類型,但無法找到任何數據。現在問題來了:

  1. 什麼是更好的編程實現這種解決方案的方式?對我來說更好表示不使用object類型的解決方案。有沒有簡單的方法來限制IList包含Item或ExtendedItem,並且沒有其他類型?
  2. 或者我應該徹底改變這個問題的方法?
  3. 或...也許這種方法是正確的,我有點過敏? ;-)

我將不勝感激任何幫助。

+0

如果你把類型的'IEnumerable的''outDict'會發生什麼?您應該能夠直接分配任何派生類型。 – krillgar

+0

我不敢相信它就這麼簡單!奇蹟般有效。如果可以,請添加一個答案,以便我可以接受它。並感謝;-) – PJDev

回答

1

如果您聲明變量outDict作爲一個集合,而不是object,那麼你就可以直接分配。

IEnumerable<Base> outDict = null; 

switch(name) { 
    case "simpleDict": 
     IList<Item> simpleDict = _dataLayer.GetSimpleDict(); 
     // ... 
     outDict = simpleDict; 
     break; 
    case "extDict": 
     IList<ExtendedItem> extDict = _dataLayer.GetExtDict(); 
     // ... 
     outDict = extDict; 
     break; 

    // ... and a few more dictionaries 
} 
+0

對不起,我感到困惑。你在評論中的回答是正確的,像魅力一樣。我剛剛犯了一個小錯誤,並在回覆您的評論後才意識到這一點。雖然這個看起來真的很好,但我會堅持第一個:-)謝謝! – PJDev

+1

我修復了我的答案以符合我的評論。我的方式是沒有必要的。 – krillgar

0

嘗試使用Interface釋放ExtendedItem的實現。使用Object for API返回可能非常有用,如果您需要在返回回調響應之前輸入dynamic以處理不同的事情。

interface Item { 
    public long ID { get; set; } 
    public string Name { get; set; } 
} 

class SimpleItem : Item { 
    public long ID { get; set; } 
    public string Name { get; set; } 
} 

class ComplicateItem: Item { 
    public long ID { get; set; } 
    public string Name { get; set; } 
    public string AdditionalProperty { get; set; } 
} 
在API控制器

然後,

Item outDict; 

    switch(name) { 
     case "simpleDict": 
      var simpleDict = _dataLayer.GetSimpleDict(); 
      // ... 
      outDict = simpleDict; 
      break; 
     case "extDict": 
      var extDict = _dataLayer.GetExtDict(); 
      // ... 
      outDict = extDict; 
      break; 

     // ... and a few more dictionaries 
    } 
+0

感謝您的反饋,但在我的情況下,對象'simpleDict'和'extDict'是對象列表,而不是簡單對象。而且,我已經在其他帖子中得到了令人滿意的答案。 – PJDev

0

你可以只返回switch語句,以及:

public IHttpActionResult GetDict(string name) 
{ 
    try 
    { 
     switch(name) { 
      case "simpleDict": 
       return Ok(_dataLayer.GetSimpleDict()); 
      case "extDict": 
       return Ok(_dataLayer.GetExtDict()); 
     } 

     SomeLogger.SomeLogging(name, outDict); 
     return Ok(new List<Item>()); 
    } 
    catch (Exception ex) 
    { 
     // Just returning error 
     return BadRequest(ex.Message); 
    } 
} 
+0

感謝您的回答。在一個簡單的例子中,這樣可以,但是在我的代碼中,我不得不爲每個交換機塊重複執行數據記錄和其他一些指令。這就是爲什麼我創建了一個局部變量 - 在最後完成一次,然後將數據返回給客戶端。 – PJDev