Reputation: 2380
I have a SignalR server that should transmit Message
objects from the server to the client. The hub-method looks like this:
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>();
}
}
The data is organized in the following way: A Message
originates from a Machine
, and a Machine
is on a Site
. A Site
in turn has multiple Machine
s. This important: Machine has no navigation property for the type Message
, but Machine
and Site
reference each other:
// Machine.cs
public virtual Site Site { get; set; }
public int SiteId { get; set; }
// Site.cs
public virtual ICollection<Machine> Machines { get; set; }
When I query the data like I showed above, everything works. But as soon as I add
.Include("Machine.Site")
the client never gets his anwser (await HubProxy.Invoke<IEnumerable<Message>>("GetMessages")
hangs forever). The funny thing is, that the hub-method returns - I tested that with log entries. This means, that the failure is somewhere in the internals of SignalR.
I assume, this is because of the Machine
and Site
entities referencing each other, causing the serialization of the objects to fail. How can I fix that?
(The client is a .NET 4.5 client, if that matters, the hub runs in IIS 8.5)
Upvotes: 3
Views: 310
Reputation: 11177
If you believe serialization is an issue, Newtonsoft.Json has 3 values for reference loop handling:
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,
}
So you can change it and testing in Global.Asax / Startup.cs:
JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Error
};
I don't know if this will help you out, but at least you can test to see if serialization is really issue of your problem.
How will you handle the error if it really is up to your design, but I'd go with some view models instead of sending raw entity objects back to the client side.
Upvotes: 0