SignalR挂在外键上

时间:2014-07-13 13:11:10

标签: .net entity-framework signalr

我有一个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来自SiteSite反过来有多个Machine。这一点非常重要:机器的Message类型没有导航属性,但 MachineSite相互引用:

// 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的内部。

我认为,这是因为MachineSite实体相互引用,导致对象的序列化失败。我该如何解决这个问题?

(客户端是.NET 4.5客户端,如果这很重要,则集线器在IIS 8.5中运行)

1 个答案:

答案 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
            };

我不知道这是否会帮助你,但至少你可以测试看看序列化是否真的是问题的问题。

如果真的取决于你的设计,你将如何处理错误,但我会使用一些视图模型,而不是将原始实体对象发送回客户端。