我通过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”的响应正文。
答案 0 :(得分:2)
很可能你启用了延迟加载。这意味着当您访问导航属性时,EF将尝试访问数据库以获取相关实体,如果DbContext
仍处于“活动状态”,这将起作用。
API调用返回数据后,JSON.NET将访问所有属性以序列化它们,包括导航属性。此时,DbContext
已经被处理掉了。这就是你得到错误的原因。
为避免这种情况,你可以:
more info on disabling lazy loading。
您还可以指示JSON.NET跳过某些属性。但是有一些麻烦的方法,你必须为你的实体添加属性。例如:
.Select()
我忘了最后一个简单的选择:你可以将你的查询投射到一个匿名类,阅读所有问题,然后返回你想要返回的JSON。
。选择(新{/ *你的投影* /});
虽然这个答案适用于旧版本,但它仍然以相同的方式工作。
注意:当你正在调试时,你仍然在DbContext
使用块内,这就是你在调试时没有出错的原因。如果您将此行:return listOfMsg;
放在using
块之外,在该行中添加断点,并观察导航属性,您还会在调试器中收到错误。