2011-03-17 2 views
2

모델 BlogPostViewModel이있는보기가 있습니다.ASP.NET MVC 폼 유효성 검사. 모델이 아닌 객체에서 어떻게합니까?

public class BlogPostViewModel 
{ 
    public BlogPost BlogPost { get; set; } 
    public PostComment NewComment { get; set; } 
} 

이보기는 조치 메소드 BlogPost에 도달 할 때 렌더링됩니다. 보기에는 블로그 게시물에 관한 정보와 Model.BlogPost.PostComments를 반복하여 블로그 게시물에 대한 의견 목록이 표시됩니다. 그 아래에는 사용자가 새로운 설명을 게시 할 수있는 양식이 있습니다. 이 양식은 다른 작업 AddComment에 게시됩니다.

 [HttpPost] 
    public ActionResult AddComment([Bind(Prefix = "NewComment")] PostComment postComment) 
    { 
     postComment.Body = Server.HtmlEncode(postComment.Body); 
     postComment.PostedDate = DateTime.Now; 
     postCommentRepo.AddPostComment(postComment); 
     postCommentRepo.SaveChanges(); 
     return RedirectToAction("BlogPost", new { Id = postComment.PostID }); 
    } 

내 문제는 유효성 검사입니다. 이 양식을 어떻게 검증합니까? 뷰의 모델은 실제로 BlogPostViewModel입니다. 나는 검증을 처음 받았고 혼란 스럽습니다. 양식은 강력한 형식의 도우미를 사용하여 BlogPostViewModelNewComment 속성에 바인딩하고 유효성 확인 도우미도 포함했습니다.

@using (Html.BeginForm("AddComment", "Blog") 
{ 
    <div class="formTitle">Add Comment</div> 
    <div> 
     @Html.HiddenFor(x => x.NewComment.PostID) @* This property is populated in the action method for the page. *@ 
     <table> 
      <tr> 
       <td> 
        Name: 
       </td> 
       <td> 
        @Html.TextBoxFor(x => x.NewComment.Author) 
       </td> 
       <td> 
        @Html.ValidationMessageFor(x => x.NewComment.Author) 
       </td> 
      </tr> 
      <tr> 
       <td> 
        Email: 
       </td> 
       <td> 
        @Html.TextBoxFor(x => x.NewComment.Email) 
       </td> 
       <td> 
        @Html.ValidationMessageFor(x => x.NewComment.Email) 
       </td> 
      </tr> 
      <tr> 
       <td> 
        Website: 
       </td> 
       <td> 
        @Html.TextBoxFor(x => x.NewComment.Website) 
       </td> 
       <td> 
        @Html.ValidationMessageFor(x => x.NewComment.Website) 
       </td> 
      </tr> 
      <tr> 
       <td> 
        Body: 
       </td> 
       <td> 
        @Html.TextAreaFor(x => x.NewComment.Body) 
       </td> 
       <td> 
        @Html.ValidationMessageFor(x => x.NewComment.Body) 
       </td> 
      </tr> 
      <tr> 
       <td> 
       </td> 
       <td> 
        <input type="submit" value="Add Comment" /> 
       </td> 
      </tr> 
     </table> 
    </div> 
} 

AddComment 동작 방법에서 유효성 검사를 구현하는 방법은 무엇입니까? 내가 Model.IsValid == false을 발견하면 그 때 무엇? 나는 무엇을 돌려 주느냐? 이 액션 메서드는 페이지의 초기 BlogPostViewModel 객체의 PostComment 속성에만 바인딩됩니다. 해당 모델의 다른 속성은 신경 쓰지 않기 때문입니다.

어떤 도움을 주셔서 감사합니다.

답변

2

모델을 다시 채우고 보도록 보내야합니다. 그러나이 작업을 수동으로 수행 할 필요는 없으며 작업 필터를 사용할 수 있습니다.

볼 : 특히

http://weblogs.asp.net/rashid/archive/2009/04/01/asp-net-mvc-best-practices-part-1.aspx#prg

: 사용법

public abstract class ModelStateTempDataTransfer : ActionFilterAttribute 
{ 
    protected static readonly string Key = typeof(ModelStateTempDataTransfer).FullName; 
} 

public class ExportModelStateToTempData : ModelStateTempDataTransfer 
{ 
    public override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     //Only export when ModelState is not valid 
     if (!filterContext.Controller.ViewData.ModelState.IsValid) 
     { 
      //Export if we are redirecting 
      if ((filterContext.Result is RedirectResult) || (filterContext.Result is RedirectToRouteResult)) 
      { 
       filterContext.Controller.TempData[Key] = filterContext.Controller.ViewData.ModelState; 
      } 
     } 

     base.OnActionExecuted(filterContext); 
    } 
} 

public class ImportModelStateFromTempData : ModelStateTempDataTransfer 
{ 
    public override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     ModelStateDictionary modelState = filterContext.Controller.TempData[Key] as ModelStateDictionary; 

     if (modelState != null) 
     { 
      //Only Import if we are viewing 
      if (filterContext.Result is ViewResult) 
      { 
       filterContext.Controller.ViewData.ModelState.Merge(modelState); 
      } 
      else 
      { 
       //Otherwise remove it. 
       filterContext.Controller.TempData.Remove(Key); 
      } 
     } 

     base.OnActionExecuted(filterContext); 
    } 
} 

:

[AcceptVerbs(HttpVerbs.Get), ImportModelStateFromTempData] 
public ActionResult Index(YourModel stuff) 
{ 
    return View(); 
} 

[AcceptVerbs(HttpVerbs.Post), ExportModelStateToTempData] 
public ActionResult Submit(YourModel stuff) 
{ 
    if (ModelState.IsValid) 
    { 
     try 
     { 
      //save 
     } 
     catch (Exception e) 
     { 
      ModelState.AddModelError(ModelStateException, e); 
     } 
    } 

    return RedirectToAction("Index"); 
} 
0

은 이렇게 : 많은 시간이 완전히 채워 모델 전달, 내가 올바른 뷰를 뷰 모델을 다시 채 웁니다 및 렌더링한다는 것을 깨달았다 보냈다

if(ModelState.IsValid) 
{ 
// Insert new comment 
.. 
.. 
// Redirect to a different view 
} 
// Something is wrong, return to the same view with the model & errors 
var postModel = new BlogPostViewModel { PostComment = postComment }; 
return View(postModel); 
+0

하지만보기, 우리가에서 게시하는 뷰가 "블로그 게시물"입니다, 내가 할 때 'View (postComment)를 반환합니다. '그것은'AddComment '또는 그 주인을 찾을 수 없다는보기입니다. 왜냐하면 t 상속인은 그 이름으로 볼 수 없습니다. – Chev

+0

'View ("BlogPost", postComment)를 반환하면 'BlogPostViewModel'인 올바른 모델 유형을 제공하지 않았기 때문에 나에게 소리 쳤습니다. 이것은'BlogPostViewModel'을 생성하고 검증을 위해 반환해야한다는 것을 의미합니까? 그렇다면 뷰 모델에서 'BlogPost' 속성을 채워야한다는 뜻입니까, 아니면 유효성 오류를 표시하기 위해 렌더링 할 때 블로그 게시물 정보가 페이지에서 사라질 것입니까? – Chev

+0

당신은 내 의견을 읽지도 않았을 수도 있습니다. 즉,'return View ("BlogPost", postComment ");' – Saxman

0

후. 고통의 종류는 아니지만 적어도 나는 무슨 일이 일어나고 있는지 이해합니다.