我有一个SignalR服务器,应该将Message
个对象从服务器传输到客户端。 hub-method看起来像这样:
public IEnumerable<Message> GetMessages()
{
try
{
using (var context = new PsmContext())
{
context.Configuration.LazyLoadingEnabled = false;
context.Configuration.ProxyCreationEnabled = false;
return context.Messages
.Include("Machine")
.ToList();
}
}
catch (Exception err)
{
Logging.Log(Logging.ServerLog, err);
return new List<Message>();
}
}
数据按以下方式组织:Message
来自Machine
,而Machine
来自Site
。 Site
反过来有多个Machine
。这一点非常重要:机器的Message
类型没有导航属性,但 Machine
和Site
相互引用:
// Machine.cs
public virtual Site Site { get; set; }
public int SiteId { get; set; }
// Site.cs
public virtual ICollection<Machine> Machines { get; set; }
当我查询上面显示的数据时,一切正常。但是一旦我添加
.Include("Machine.Site")
客户端永远不会得到他的anwser(await HubProxy.Invoke<IEnumerable<Message>>("GetMessages")
永远挂起)。有趣的是,hub-method返回 - 我用日志条目测试了它。这意味着失败发生在SignalR的内部。
我认为,这是因为Machine
和Site
实体相互引用,导致对象的序列化失败。我该如何解决这个问题?
(客户端是.NET 4.5客户端,如果这很重要,则集线器在IIS 8.5中运行)
答案 0 :(得分:0)
如果您认为序列化是一个问题,Newtonsoft.Json有3个参考循环处理值:
public enum ReferenceLoopHandling
{
// Summary:
// Throw a Newtonsoft.Json.JsonSerializationException when a loop is encountered.
Error = 0,
//
// Summary:
// Ignore loop references and do not serialize.
Ignore = 1,
//
// Summary:
// Serialize loop references.
Serialize = 2,
}
因此,您可以在Global.Asax / Startup.cs中更改它并进行测试:
JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Error
};
我不知道这是否会帮助你,但至少你可以测试看看序列化是否真的是问题的问题。
如果真的取决于你的设计,你将如何处理错误,但我会使用一些视图模型,而不是将原始实体对象发送回客户端。