2011-08-11 35 views
1

我試圖添加一個表單以允許用戶評論我的博客應用程序上的帖子。到目前爲止,我已向表單添加了帖子詳細信息視圖,並且我可以提交註釋,並將它們正確添加到我的數據庫中。但是,我向用戶顯示驗證錯誤時遇到問題。評論表單包含在部分視圖中,並在帖子詳細信息視圖中使用Html.RenderAction進行呈現。我想強調的是,我不想爲此使用AJAX,因爲我希望從逐步增強的角度來解決這個問題。ASP.NET MVC3:從父視圖中的子視圖顯示驗證錯誤

這裏的相關帖子行動:

[HttpPost, Authorize] 
public ActionResult AddComment(CommentViewModel newComment) 
{ 
    if (ModelState.IsValid) 
    { 
     Comment comment = new Comment(_userRepository.GetByUsername(User.Identity.Name)); 
     Mapper.Map(newComment, comment); 

     _commentRepository.Add(comment); 

     _postsRepository.CommentAdded(comment.Article); 

     return RedirectToAction("Index", new { id = newComment.PostID }); 
    } 

    // What do I do here? 
} 

我已經試過這裏返回意見的幾種方法,但我的問題是更加複雜的,我在父行動正在進行一些控制器參數驗證:

// 
// GET: /Posts/5/this-is-a-slug 

public ActionResult Index(int id, string slug) 
{ 
    PostViewModel viewModel = new PostViewModel(); 
    var model = _postsRepository.GetByID(id); 

    if (model != null) 
    { 
     if (slug == null || slug.CompareTo(model.Slug) != 0) 
     { 
      return RedirectToActionPermanent("Index", new { id, slug = model.Slug }); 
     } 
     else 
     { 
      _postsRepository.PostVisited(model); 

      Mapper.Map(model, viewModel); 

      viewModel.AuthorName = _userRepository.GetById(model.AuthorID); 
     } 
    } 

    return View(viewModel); 
} 

此操作基本上模仿SO的URL如何工作。如果提供了帖子ID,則帖子從數據庫中取出,同時創建帖子時創建塊。如果URL中的slu does與數據庫中的slu match不匹配,它將重定向爲包含slu。。這是工作很好,但它確實意味着我在想填充我父視圖模型,這是問題如下:

public class PostViewModel 
{ 
    public int PostID { get; set; } 
    public string Title { get; set; } 
    public string Body { get; set; } 
    public string Slug { get; set; } 
    public DateTime DatePublished { get; set; } 
    public int NumberOfComments { get; set; } 
    public int AuthorID { get; set; } 
    public string AuthorName { get; set; } 

    public List<CommentViewModel> Comments { get; set; } 
    public CommentViewModel NewComment { get; set; } 
} 

我希望會的工作是填充PostViewModel.NewComment,測試以查看它是否有數據然後用它來顯示任何模型錯誤。不幸的是,我失去了如何實現這一點。 This question幫助我塑造了我的方法,但它並沒有完全回答我的問題。

有人能給我一個正確的方向輕輕推?如果我的方法看起來不合理,我想知道爲什麼以及可能的解決方案是什麼。

非常感謝提前。

回答

2

忘記填寫我的答案在這裏。對於偶然發生的任何事情,答案是使用TempData來存儲ModelState錯誤,然後在相關控制器操作中重新填充ModelState

首先,我在控制器中聲明瞭一個關鍵字,用於引用TempData中的數據。我決定以CommentViewModel類型爲基礎,因爲這兩個操作都依賴於它。

public class PostsController : Controller 
{ 
    private static readonly string commentFormModelStateKey = typeof(CommentViewModel).FullName; 
    // Rest of class. 
} 

在第一個操作中,代碼檢查TempData是否包含分配給密鑰的數據。如果是,則將其複製到ModelState

// GET: /posts/comment 
[ChildActionOnly] 
public PartialViewResult Comment(PostViewModel viewModel) 
{ 
    viewModel.NewComment = new CommentViewModel(viewModel.PostID, viewModel.Slug); 

    if (TempData.ContainsKey(commentFormModelStateKey)) 
    { 
     ModelStateDictionary commentModelState = TempData[commentFormModelStateKey] as ModelStateDictionary; 
     foreach (KeyValuePair<string, ModelState> valuePair in commentModelState) 
      ModelState.Add(valuePair.Key, valuePair.Value); 
    } 

    return PartialView(viewModel.NewComment); 
} 

此操作確定的ModelState是添加註釋到數據庫之前有效。如果ModelState無效,則將其複製到TempData,這使其可用於第一個操作。

// POST: /posts/comment 
[HttpPost, Authorize] 
public ActionResult Comment(CommentViewModel newComment) 
{ 
    if (!ModelState.IsValid) 
    { 
     TempData.Add(commentFormModelStateKey, ModelState); 
     return Redirect(Url.ShowPost(newComment.PostID, newComment.Slug)); 
    } 

    // Code to add a comment goes here. 
} 
相關問題