2016-11-23 22 views
5

Tôi đã cố gắng thiết lập bản trình diễn nhỏ, trong đó một bài viết có nhiều nhận xét. Chế độ xem chi tiết bài viết, sẽ hiển thị các nhận xét trong chế độ xem từng phần. Bản thân partialView chứa một phần xem khác để thêm một chú thích mới.Tại sao PartialView tiếp tục tự gọi?

Khi tôi cố gắng thêm một nhận xét khác, tôi nhận được InsufficientExecutionStackException, vì hành động trong bộ điều khiển tiếp tục tự gọi. Lý do tại sao điều này xảy ra?

(Nếu ai đó có tài liệu khóa học trong tầm tay Một ví dụ tương tự nên có ít mô-đun 9 trong 70-486 nhiên từ MSFT, đó là những gì tôi cố gắng xây dựng..)

Edit: Mã đầy đủ là trên github

Chỉnh sửa2: Mẫu trên Github đã được sửa. Như Stephen Muecke đã chỉ ra, thực tế, cả mũ mũ GETPOST cùng tên đã gây ra tham chiếu vòng tròn. Trước khi có thêm nhiều người chỉ ra rằng các Mô hình DI và Chế độ xem bị thiếu và việc hiển thị lại tất cả nhận xét là không tối ưu: Có, tôi biết và không, những thứ đó không là gì, mà tôi muốn hoàn thành. Đây chỉ là một bản demo bẩn nhanh chóng.

Bộ điều khiển:

[ChildActionOnly] 
public PartialViewResult _GetCommentsForArticle(int articleId) 
{ 
    ViewBag.ArticleId = articleId; 
    var comments = db.Comments.Where(x => x.Article.ArticleId == articleId).ToList(); 
    return PartialView("_GetCommentsForArticle", comments); 
} 


public PartialViewResult _CreateCommentForArticle(int articleId) 
{ 
    ViewBag.ArticleId = articleId; 
    return PartialView("_CreateCommentForArticle"); 
} 

[HttpPost] 
public PartialViewResult _CreateCommentForArticle(Comment comment, int articleId) 
{ 
    ViewBag.ArticleId = articleId; 
    comment.Created = DateTime.Now; 
    if (ModelState.IsValid) 
    { 
     db.Comments.Add(comment); 
     db.SaveChanges(); 
    } 
    var comments = db.Comments.Where(x => x.Article.ArticleId == articleId).ToList(); 
    return PartialView("_GetCommentsForArticle", comments); 
} 

dòng có liên quan trong Details.cshtml cho Điều:

@Html.Action("_GetCommentsForArticle", "Comments", new { articleId = Model.ArticleId}) 

_GetCommentsForArticle:

@model IEnumerable<Mod9_Ajax.Models.Comment> 
<div id="all-comments"> 
    <table class="table"> 
     <tr> 
      <th> 
       @Html.DisplayNameFor(model => model.Text) 
      </th> 
     </tr> 

     @foreach (var item in Model) 
     { 
      @* ... *@ 
     } 
    </table> 
</div> 
@Html.Action("_CreateCommentForArticle", "Comments", new { articleId = ViewBag.ArticleId }) 

_CreateCommentForArticle:

@model Mod9_Ajax.Models.Comment 
@using (Ajax.BeginForm("_CreateCommentForArticle", "Comments", new AjaxOptions 
{ 
    HttpMethod = "POST", 
    InsertionMode = InsertionMode.Replace, 
    UpdateTargetId = "all-comments" 
})) 
{ 
    @* ... *@ 

     <div class="form-group"> 
      <div class="col-md-offset-2 col-md-10"> 
       <input type="submit" value="Create" class="btn btn-default" /> 
      </div> 
     </div> 
    </div> 
} 
+0

Là một sang một bên, nếu tài liệu đào tạo được hướng dẫn bạn sử dụng một lớp mô hình thực thể như một ViewModel hoặc DTO sau đó tôi nên cho bạn biết đó là thực hành xấu - luôn luôn sử dụng một loại ViewModel/DTO chuyên dụng thay vì tái sử dụng các loại mô hình thực thể. – Dai

+1

Tôi vừa sao chép các khung nhìn của bạn trong một dự án trống mới với một hành động 'CommentsController :: Details' đơn giản và tôi không thể tái tạo vấn đề này. Bạn có thể đăng toàn bộ dự án của mình vào một tệp Zip/lưu trữ ở đâu đó không? – Dai

+0

Tại sao bạn POST phương thức trả về tất cả các bình luận khi bạn đã có chúng trong khung nhìn (trái với việc chỉ thêm chú thích mới vào khung nhìn) –

Trả lời

1

Để giải thích điều gì đang xảy ra, bạn có một biểu mẫu gửi cho bạn phương thức _CreateCommentForArticle(), sau đó hiển thị phần _GetCommentsForArticle.cshtml một phần của bạn bao gồm @Html.Action("_CreateCommentForArticle", ...).

Trong phương thức GET ban đầu cho Details() quan điểm sẽ được trả lại một cách chính xác, nhưng khi bạn gửi biểu mẫu, yêu cầu hiện tại cho trang _GetCommentsForArticle là một phương pháp [HttpPost], vì vậy @Html.Action() sẽ tìm kiếm một phương pháp [HttpPost] (không phải là phương pháp [HttpGet]). Điều đó [HttpPost] lần lượt ám _GetCommentsForArticle.cshtml một phần và một lần nữa gọi các phương pháp POST _CreateCommentForArticle() POST mà ám _GetCommentsForArticle.cshtml một phần và như vậy cho đến khi bạn hết bộ nhớ và ngoại lệ được ném.

Bạn có thể giải quyết việc này bằng cách thay đổi tên của phương thức POST, ví dụ

[HttpPost] 
public PartialViewResult Create(Comment comment, int articleId) 

và sửa đổi các hình thức cho phù hợp với

@using (Ajax.BeginForm("Create", "Comments", new AjaxOptions { ... 
+0

Tôi vừa ngồi trong phòng thí nghiệm và đi đến cùng một kết luận. Điều này là một cách chính xác những gì đã thất bại. Khi tôi đã trang trí hành động với '[HttpPost, ActionName (" _ PostCreate ")]' và sửa đổi 'Ajax.BeginForm' nó đã bắt đầu hoạt động. – Marco

+0

Có rất nhiều mã không cần thiết trong ứng dụng của bạn và bạn làm giảm hiệu suất bằng cách thực hiện ít nhất 2 cuộc gọi cơ sở dữ liệu không cần thiết. Khi tôi có cơ hội, tôi sẽ cập nhật câu trả lời với một số nhận xét khác. –

+0

Tôi hoàn toàn nhận thức được tất cả (tốt, hầu hết) thiếu sót. Tôi đã gãi đầu về tham chiếu vòng tròn. Mã này là mẫu mvc mặc định từ studio trực quan và sau đó chỉ cần thêm các mô hình và DAL để chứng minh quan điểm của tôi. (Và đây thực sự là cách mà khóa học 70-486 thể hiện Ajax. Chỉ cần kiểm tra lại) – Marco

Các vấn đề liên quan