2012-10-02 48 views
1

我在過去的幾個星期裏一直在學習MVC3,我試圖寫出我認爲應該是一個足夠簡單的功能塊,但是我遇到了讓它正常工作的實際問題。如何使用MVC3製作新聞頁面,並通過內嵌評論發佈?

場景

我的網站將包含新聞的帖子,總結了主頁上,有鏈接可查看在自己的頁面每篇文章的全部細節。

可以對每篇文章進行評論,這些評論會顯示在每篇文章的詳細信息頁面末尾。經過身份驗證的用戶應該能夠將自己的評論發佈到顯示文章本身的頁面上。我想避免用戶被帶到一個單獨的頁面(儘管我從代碼的角度理解這更容易,但我不同意這是一個很好的UX!)。

舉一個我想如何看的例子,Scott Hanselman的博客(http://www.hanselman.com)就是一個完美的例子(儘管他的主頁顯示的是整篇文章,而不僅僅是摘要!) - 它鏈接到評論頁面,並且「添加評論」表格整齊地位於底部,與文章一致。

我在哪裏至今

我已經成功地寫我的新聞欄目的控制器,與指數的方法(以檢索最近發表的X號)和「評論」的方法以顯示完整的文章和評論。我還用它自己的Controller方法創建了一個名爲「CommentForm」的部分視圖。從下面的控制代碼片段:

// 
// GET: /News/ 
public ActionResult Index() 
{ 
    using (var nm = new NewsManager()) 
    { 
     var news = nm.GetLatestActiveNewsArticles(50, "System"); 
     return View(news); 
    } 
} 
// 
// GET: /News/Comments/20 
public ActionResult Comments(int id) 
{ 
    using (var nm = new Rapallo.Core.Managers.NewsManager()) 
    { 
     var article = nm.GetArticle(id); 
     return View(article); 
    } 
} 
// GET: /News/CommentForm/20 
[HttpGet()] 
public ActionResult CommentForm(int newsId) 
{ 
    return View(new Rapallo.DataAccess.Comment() { NewsId = newsId }); 
} 
// 
// POST: /News/Comments/20 
[Authorize()] 
[HttpPost()] 
public ActionResult Comments(Comment comment) 
{ 
    using (var nm = new NewsManager()) 
    { 
     var article = nm.GetArticle(comment.NewsId.Value); 
     if (null == article) HttpNotFound(); 
    } 
    using (var cm = new CommentManager()) 
    { 
     if (cm.AddCommentToNews(comment.NewsId.Value, CurrentUser.RapalloUser.Id, comment.Body)) 
     return RedirectToAction("Comments", "News", new { id = comment.NewsId.Value }); 
    } 
    return HttpNotFound(); 
} 

而且從評論來看,代碼片段展示,我想我的新增評論形式:

@if (User.Identity.IsAuthenticated) 
{ 
    @Html.Partial("Comment", new Rapallo.DataAccess.Comment() { NewsId = Model.Id }); 
} 

這種觀點規定:

@model Rapallo.DataAccess.News 

最後,評論表本身:

@model Rapallo.DataAccess.Comment 
@using (Html.BeginForm()) 
{ 
    @Html.TextAreaFor(m => m.Body); 
    <input type="submit" value="Send Comment" /> 
} 

問題

概括地說,當我提交評論表單(這使得正確),NewSID的對Comment模型未填充,因此控制器可以與正確的消息後新註釋不相關聯。

如果有人能指出我哪裏出錯了,我將不勝感激!我試圖調整NerdDinner的一些代碼來完成這項工作,以及在列車上花費無數個小時嘗試部分視圖,不同模型的各種組合,甚至在我的控制器中重命名方法以試圖使其發揮作用。

我非常熱衷於將「添加評論」功能封裝到它自己的單獨窗體中,並且能夠使用它來添加評論,而不僅僅是新聞文章。數據庫模式和域模型已經支持這個,我只是無法讓UI工作。

任何幫助將非常歡迎和感激地收到。

回答

1

簡單的答案是,你需要有你的窗體上NewsId的表示爲模型聯編程序找到它。所以,您的評論的形式更改爲:

@model Rapallo.DataAccess.Comment 
@using (Html.BeginForm()) 
{ 
    @Html.HiddenForm(m => m.NewsId); 
    @Html.TextAreaFor(m => m.Body); 
    <input type="submit" value="Send Comment" /> 
} 
+0

第一次工作,謝謝。我一直忘記這不是ASP.NET WebForms,也沒有ViewState!謝謝 :) –

1

我們必須解決類似的問題,但不是使用HTML表單,而是選擇基於JavaScript的解決方案將消息發佈到API控制器。

Detail.aspx

<!-- Display the Content (i.e. News Story, Product, etc --> 
<%= Html.DisplayFor(n => Model.Content[Model.Content.PageIndex], "ReleaseFull")%> 
<!-- Display the comments and form. Pass in the type of content and the Id --> 
<% Html.RenderAction("Commenting", "Home", new { area = "Reviews", 
    contentTypeName = "product", 
    contentTypeId = ContentType.Product, 
    contentId = Model.Content[Model.Content.PageIndex].Id }); %> 

談到控制器

[ChildActionOnly] 
public ActionResult Commenting(string contentTypeName, int contentTypeId, int contentId) 
{ 
    //psuedo-code to get comments 
    var comments = CommentingAPI.GetCommentsForContentType(contentTypeId, contentId); 

    var viewModel = new CommentsListing 
    { 
     Comments = comments, 
     ContentId = contentId, 
     ContentTypeId = contentTypeId, 
     ContentTypeName = contentTypeName 
    }; 
    return View(viewModel); 
} 

Commenting.aspx

<%@ Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage<Website.ViewModels.CommentsListing>" %> 

<div id="commenting" class="commenting"> 
     <h3 class="h2">Comment and then share on Facebook &amp; Twitter</h3> 
     <div class="arrow"></div> 
     <textarea placeholder="Type your comment here..." class="w100 p10 tMrg10" cols="40" rows="4" id="commentText></textarea> 
     <div class="textarea-support"> 
      <span class="post-action"> 
       <span id="commentButton"><a class="btn l-btn-lg">Post Comment</a></span> 
      </span> 
     </div> 

    <!-- Insert new comments here so they show up at the top of the listing --> 
    <div id="newComments"></div> 

    <% foreach (var comment in Model.Comments) { %> 
     <!-- Display the comments here --> 
     <% var memberComment = comment; %><%= Html.DisplayFor(c => memberComment)%> 
    <% } %> 
</div> 

<script type="text/javascript"> 
    //using a custom jQuery plugin we hook up the commenting section 
    //when the user clicks "Post Comment" the message is posted to 
    //another Controller using $.ajax({ type:POST }); 
    //The controller stores the comment in the database and returns an instance of the comment 
    $(function() { 
     $('#commenting').commenting({ 
      contentTypeTypeId: <%: Model.ContentTypeId %>, 
      contentId: <%: Model.ContentId %>, 
      isAuthenticated: <%= Html.IsMember() %> 
    }); 
</script> 
+0

感謝您的回答 - 這是對我怎麼能AJAXify我的UI在未來所以肯定一個牢記一個很好的解釋! –

相關問題