将评论添加到Post,SignalR时出错

时间:2014-04-20 22:21:33

标签: json.net signalr signalr-hub signalr.client

好的,我在ASP.NET MVC 4项目中使用SignalR,Web API 2,JQuery和KnockoutJS设置了一个简单的聊天应用程序。

用户必须登录才能发布或发表评论。当他们发布或评论帖子时,它会转到Hub并将该帖子/评论插入到数据库中。在加载聊天页面时,会向API控制器发出$ .get调用,以获取与每个帖子相关的所有帖子和评论。

public IList<Post> Get()
{
    var allPosts = this.db.Posts.OrderByDescending(x => x.DatePosted).ToList();
    foreach (var post in allPosts)
    {
        var allCommentsOnThisPost = db.Comments.Where(p => p.ParentPost.PostId == post.PostId).ToList();
        foreach (var comment in allCommentsOnThisPost)
        {
             post.Comments.Add(comment);
        }

        return allPosts;
    }
}

此工作正常,所有过去的帖子和评论都会添加到视图中。但是,如果用户尝试向帖子上一篇帖子添加评论(在刷新页面之前发布的帖子),则对该集团的调用将失败,并显示以下详细错误消息:

[17:10:30 GMT-0500 (Central Daylight Time)] SignalR: Error converting value {null} to type 'System.Int32'. Path '', line 1, position 4.
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Microsoft.AspNet.SignalR.Json.JRawValue.ConvertTo(Type type)
   at Microsoft.AspNet.SignalR.Hubs.DefaultParameterResolver.ResolveParameter(ParameterDescriptor descriptor, IJsonValue value)
   at System.Linq.Enumerable.<ZipIterator>d__7a`3.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at Microsoft.AspNet.SignalR.Hubs.DefaultParameterResolver.ResolveMethodParameters(MethodDescriptor method, IList`1 values)
   at Microsoft.AspNet.SignalR.Hubs.HubDispatcher.InvokeHubPipeline(IHub hub, IJsonValue[] parameterValues, MethodDescriptor methodDescriptor, HubRequest hubRequest, StateChangeTracker tracker). jquery.signalR-2.0.3.js:76
[17:10:30 GMT-0500 (Central Daylight Time)] SignalR: chathub.AddComment failed to execute. Error: Error converting value {null} to type 'System.Int32'. Path '', line 1, position 4. 

我的课很简单:

public class Post
{
    [Key]
    public int PostId { get; set; }
    public string Message { get; set; }
    public string Username { get; set; }
    public DateTime DatePosted { get; set; }
    public virtual ICollection<Comment> Comments { get; set; }
}

public class Comment
{
    [Key]
    public int CommentId { get; set; }
    public string Message { get; set; }
    public string Username { get; set; }
    public DateTime DatePosted { get; set; }
    public virtual Post ParentPost { get; set; }
}

ChatHub:

public class ChatHub : Hub
    {
        public void WritePost(string username, string message)
        {
            var db = new DBContext();
            var post = new Post { Message = message, Username = username, DatePosted = DateTime.Now };
            db.Posts.Add(post);
            db.SaveChanges();

            Clients.All.receivedNewPost(post.PostId, post.Username, post.Message, post.DatePosted);
        }

        public void AddComment(int postId, string comment, string username)
        {
            var db = new DBContext();
            var post = db.Posts.FirstOrDefault(p => p.PostId == postId);

            if (post != null)
            {
                var newComment = new Comment { ParentPost = post, Message = comment, Username = username, DatePosted = DateTime.Now };
                db.Comments.Add(newComment);
                db.Entry(post).State = EntityState.Modified;
                db.SaveChanges();

                Clients.All.receivedNewComment(newComment.ParentPost.PostId, newComment.CommentId, newComment.Message, newComment.Username, newComment.DatePosted);
            }
        }
    }

所以我想知道的是,错误是否与Newtonsoft JSON序列化/反序列化有关。正如您在上面的代码中看到的那样,帖子和评论使用DateTime.Now时间戳存储在数据库中,因此我不确定问题是什么?

任何帮助将不胜感激!

编辑:以下是相关的客户端代码:

(function () {
    var hub = $.connection.chatHub;
    $.connection.hub.logging = true;
    $.connection.hub.start().done(function () {
        loadPosts();
    });

  function loadPosts() {
        $.get('/api/posts', function (data) {
            var postsArray = [];
            for (var i = 0; i < data.length; i++) {
                var newPost = new post(data[i].Id, data[i].Message, data[i].Username, data[i].DatePosted);
                if (data[i].Comments != null) {
                    for (var j = 0; j < data[i].Comments.length; j++) {
                        var newComment = new comment(data[i].Comments[j].Id, data[i].Comments[j].Message, data[i].Comments[j].Username, data[i].Comments[j].DatePosted);
                        newPost.comments.push(newComment);
                    }
                }
                vm.posts.push(newPost);
            }
        });
    }

var vm = {
        posts: ko.observableArray([]),
        notifications: ko.observableArray([]),
        username: ko.observable('@SignalR.UsersDictionary.UsersDict[User.Identity.Name]'),
        writePost: function () {
            if ($('#message').val().length > 0) {
                $.connection.chatHub.server.writePost(vm.username(), $('#message').val()).done(function () {
                    $('#message').val('');
                });
            }
        },
    }

 var post = function (id, message, username, date) {
        this.id = id;
        this.message = message;
        this.username = username;
        this.date = date;
        this.comments = ko.observableArray([]);

        this.addComment = function (context) {
            var comment = $('input[name="comment"]', context).val();
            if (comment.length > 0) {
                $.connection.chatHub.server.addComment(this.id, comment, vm.username())
                .done(function () {
                    $('input[name="comment"]', context).val('');
                });
            }
        };
    }

  var comment = function (id, message, username, date) {
        this.id = id;
        this.message = message;
        this.username = username;
        this.date = date;
    }

 $(function () {
        ko.applyBindings(vm);
    });
  }());

1 个答案:

答案 0 :(得分:2)

错误表示当您拨打hub.addComment()时,postId参数的值为nullundefined且序列化程序不知道如何将其转换为期望的类型(int)。

所以你需要从那里追溯它(在调用集线器的线路上设置一个断点)。由于您没有发布客户端代码,因此我们无法提供帮助。