좋아요. 그렇기 때문에 SignalR, Web API 2, JQuery 및 KnockoutJS를 사용하는 ASP.NET MVC 4 프로젝트에 간단한 채팅 앱을 설정했습니다.Post, SignalR에 코멘트를 추가하는 중 오류가 발생했습니다.
사용자는 로그인하거나 코멘트에 로그인해야합니다. 게시물에 게시물을 올리거나 댓글을 달면 허브로 이동하여 해당 게시물/설명을 데이터베이스에 삽입합니다. 채팅 페이지가로드되면 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 :
오류가 Newtonsoft JSON 직렬화/역 직렬화 함께 할 수있는 뭔가가있는 경우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);
}
}
}
그래서 내가 궁금하네요 것은. 위의 코드에서 볼 수 있듯이 Posts 및 Comments는 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);
});
}());
Lars를 지적 해 주셔서 감사합니다. 문제는 내 고객 측 코드에 실제로있었습니다. loadPosts 함수에서 뷰에 추가 된 각 게시물의 "PostId"대신 "Id"를 설정했습니다. PostId로 변경되어 매우 효과적입니다! – pmalbu