【发布时间】:2020-11-07 20:41:14
【问题描述】:
当我尝试从客户端发送要在复杂类中表示的对象时,SignalR 因某种原因失败。
下面的客户端代码工作正常...
connection.send("ABC", "111", "222", { text: "text" }).then(() => console.log("sent")).catch((r) => console.log(r))
...对于下面的服务器端代码
public async Task ABC(string a, string b, User c)
{
await Clients.All.SendAsync(RECEIVE, a, b, c);
}
public class User
{
public string Text { get; set; }
public string Name { get; set; }
}
下面的不起作用....
connection.send("ABC", "111", "222", { text: "text", jsonOptions: [] }).then(() => console.log("sent")).catch((r) => console.log(r))
...对于下面的服务器端代码
public async Task ABC(string a, string b, Post c)
{
await Clients.All.SendAsync(RECEIVE, a, b, c);
}
public class Post
{
public int Id { get; set; }
[Required] [StringLength(450, ErrorMessage = "Sender id cannot be more than 450")]
public string SenderId { get; set; }
[Required] [StringLength(30, ErrorMessage = "Sender name cannot be more than 30")]
public string SenderName { get; set; }
[StringLength(300, ErrorMessage = "Senderpic length must not be more than 300")]
public string SenderPic { get; set; }
public PostLocation PostLocation { get; set; }
public int? CourseId { get; set; }
public int ClassId { get; set; }
public int? ChatId { get; set; }
public int? LectureId { get; set; }
[Required] [StringLength(2000, ErrorMessage = "Post text cannot be more than 2000")]
public string Text { get; set; }
[Required]
public DateTimeOffset TimeStamp { get; set; }
[NotMapped]
public int Upvotes { get; set; }
[NotMapped]
public ICollection<string> UpvoteIds { get; set; }
[NotMapped]
public ICollection<string> DownvoteIds { get; set; }
[NotMapped]
public ICollection<string> StarredIds { get; set; }
public PostType Type { get; set; }
public bool IsReply { get; set; }
[ForeignKey(nameof(FullRepliedPost))]
public int? RepliedId { get; set; }
[NotMapped]
public MiniPost RepliedPost { get; set; }
[StringLength(300, ErrorMessage = "ProfilePicturePath length must not be more than 300")]
public string AttachmentPath { get; set; }
public AttachmentType AttachmentType { get; set; }
public int AnsweredPostId { get; set; }
public Choice CorrectAnswer { get; set; }
public string JsonOptions { get; set; }
[NotMapped]
public ICollection<string> Options => (ICollection<string>)
JsonConvert.DeserializeObject(JsonOptions, typeof(ICollection<string>));
[NotMapped]
public ICollection<string> ASelectionIds { get; set; }
[NotMapped]
public ICollection<string> BSelectionIds { get; set; }
[NotMapped]
public ICollection<string> CSelectionIds { get; set; }
[NotMapped]
public ICollection<string> DSelectionIds { get; set; }
[NotMapped]
public ICollection<string> ESelectionIds { get; set; }
#region navigation properties
[JsonIgnore]
public Post FullRepliedPost { get; set; }
[JsonIgnore]
public ICollection<PostVote> PostVotes { get; set; }
[JsonIgnore]
public ICollection<PostStar> PostStars { get; set; }
[JsonIgnore]
public ICollection<MultiChoice> OptionSelections { get; set; }
[JsonIgnore] [ForeignKey(nameof(RepliedId))]
public ICollection<Post> Replies { get; set; }
#endregion
}
我将上面的 Post 类用作业务对象,这就是它具有所有这些属性的原因。我想知道这是否与失败有关。我在 Chrome 开发工具中收到以下错误
[2020-11-07T20:19:42.768Z] Information: Connection disconnected.
当我再次尝试发送时,我收到一条错误消息,提示我在 signalR 断开连接时无法发送消息。
编辑:我在此处粘贴的代码 (jsonOptions: []) 中省略了一些内容,结果证明这是问题的实际原因。
【问题讨论】:
-
实体类不是 DTO。也就是说,“连接断开”消息可能是无关的(请注意,它不是错误级别的消息,只是信息级别的消息)。
-
如果您启用了延迟加载,那么可能发生的情况是 SignalR 正在序列化您的整个数据库 - 我希望您能看到那里的问题...
-
@Dai。我也觉得这是一个序列化问题。我将一点一点地剥离这个类,直到我看到是什么属性导致了错误。或者也许我应该换一种方式去做。我不知道只发送帖子的 ID 并让接收者从服务器获取帖子是否更好。
-
“或者我应该换一种方式”你应该!因为你不应该直接序列化实体类。 您需要定义一个专用的 DTO 类型。
标签: asp.net-core signalr