列表与LT;>在调试模式下查看它后表现不同

时间:2015-11-23 10:45:37

标签: c# json entity-framework asp.net-web-api

我通过Web-Api访问数据库中的数据,并将其作为Json字符串发送回UWP-App。

MessageRepository.cs:

public List<Message> GetByRecipientId(int id)
{
   var listOfMsg = new List<Message>();
   using (var ctx = new ShowcaseContext())
   {
      var recipientWithId = ctx.Recipients.Where(rec => rec.UserId == id);

      foreach (var recipient in recipientWithId.ToList())
      {
         var msgWithId = ctx.Messages.Where(msg => msg.Id == recipient.MessageId);
         listOfMsg.Add(msgWithId.Single());
      }

      return listOfMsg;
   }
}

MessageController.cs:

[Route("api/message/recipient/{id}")]
public IEnumerable<Message> GetByRecipientId(int id)
{
   return messageRepository.GetByRecipientId(id);
}

问题是我得到了

  

“Newtonsoft.Json.JsonSerializationException”错误

尝试将listOfMsg返回到UWP-App时 但是,如果我在调试模式中查看List<>及其项目,或者在返回之前访问List<>中的特定消息,则错误消失,我在UWP-App中获得正确的数据。登记/> 似乎List<>在访问它之前具有不同的格式,但无法序列化 有谁知道为什么?

修改
Message.cs:

public class Message
{
    public int Id { get; set; }
    public virtual Collection<Recipient> Recipients { get; set; }
    public MessageTrigger Trigger { get; set; }
    public string Body { get; set; }
    public DateTime CreatedTs { get; set; }
}

StackTrace为null,但错误消息为

  

“ObjectContent`1”类型无法序列化内容类型“application / json; charset = utf-8”的响应正文。

1 个答案:

答案 0 :(得分:2)

很可能你启用了延迟加载。这意味着当您访问导航属性时,EF将尝试访问数据库以获取相关实体,如果DbContext仍处于“活动状态”,这将起作用。

API调用返回数据后,JSON.NET将访问所有属性以序列化它们,包括导航属性。此时,DbContext已经被处理掉了。这就是你得到错误的原因。

为避免这种情况,你可以:

more info on disabling lazy loading

替代方案:Json配置

您还可以指示JSON.NET跳过某些属性。但是有一些麻烦的方法,你必须为你的实体添加属性。例如:

替代方案:使用.Select()

投射到anonymus类

我忘了最后一个简单的选择:你可以将你的查询投射到一个匿名类,阅读所有问题,然后返回你想要返回的JSON。

。选择(新{/ *你的投影* /});

虽然这个答案适用于旧版本,但它仍然以相同的方式工作。

注意:当你正在调试时,你仍然在DbContext使用块内,这就是你在调试时没有出错的原因。如果您将此行:return listOfMsg;放在using块之外,在该行中添加断点,并观察导航属性,您还会在调试器中收到错误。