2016-12-20 49 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