2009-03-23 3 views
2

AJAX 양식을 사용하여 항목을 데이터베이스로 업데이트하고 있습니다. 완료되면 모든 항목을 다시 나열하고 모두 테이블에 표시하는 부분보기를 반환합니다. 컨트롤러 작업에 모델 상태 오류를 추가해야 할 때 문제가 발생합니다. ValidationMessage를 사용하여 사용자에게 오류를 표시하려고하므로 모델 상태 오류가 발생하면 항목 목록을 반환하지 않습니다. 나의 생각은 내가 내 컨트롤러에이 같은 뭔가를 할 수 있다는 것입니다 :Ajax 양식이있는 Modelstate

 [AcceptVerbs(HttpVerbs.Post)] 
    public ActionResult UpdateNewsItem(int newsID, string newsTitle, string newsDescription, string newsBeginningDate, string newsEndingDate) 
    { 
     List<Models.News> lstNewsItem = new List<News>(); 

     //we need to grab the member so we can capture the user id 
     //for the corresponding news property 
     MembershipUser member = Membership.GetUser(User.Identity.Name); 

     //the news instance to use in case the viewdata is invalid 
     Models.News newsError = new Models.News(); 

     //create the datetime objects 
     DateTime dtBeginningDate = DateTime.MinValue; 
     DateTime dtEndingDate = DateTime.MaxValue; 

     //the message we want to send whenever the user enters an invalid date 
     string strInvalidDateError = "Invalid date. Please use a format like '12/25/2008'"; 

     //clean user input 
     newsTitle = Models.clsGlobals.CleanString(newsTitle); 
     newsDescription = Models.clsGlobals.CleanParagraph(newsDescription); 

     //newsTitle 
     if (string.IsNullOrEmpty(newsTitle)) 
     { 
      newsError.Title = string.Empty; 
      ModelState.AddModelError("newsTitle", "You must enter a news title."); 
     } 

     //description 
     if (string.IsNullOrEmpty(newsDescription)) 
     { 
      newsError.Description = string.Empty; 
      ModelState.AddModelError("newsDescription", "You must enter a news description."); 
     } 

     //beginningDate 
     if (string.IsNullOrEmpty(newsBeginningDate)) 
     { 
      ModelState.AddModelError("newsBeginningDate", "You must enter a beginning date."); 
     } 

     //endingDate 
     if (string.IsNullOrEmpty(newsEndingDate)) 
     { 
      ModelState.AddModelError("newsEndingDate", "You must enter an ending date."); 
     } 

     //set the beginning date 
     try 
     { 
      dtBeginningDate = DateTime.Parse(newsBeginningDate); 
      newsError.BeginningDate = dtBeginningDate; 
     } 

     catch (FormatException) 
     { 
      ModelState.AddModelError("newsBeginningDate", strInvalidDateError); 
     } 

     //set the ending date 
     try 
     { 
      dtEndingDate = DateTime.Parse(newsEndingDate); 
      newsError.EndingDate = dtEndingDate; 
     } 

     catch (FormatException) 
     { 
      ModelState.AddModelError("newsEndingDate", strInvalidDateError); 
     } 

     //data is validated, so we can begin the update 
     if (ModelState.IsValid == true) 
     { 

      try 
      { 
       //use to perform actions on db 
       Models.NewsDataContext dcNews = new Models.NewsDataContext(); 

       //fetch the items that match what the user requested to edit 
       lstNewsItem = this.GetNewsItem(newsID); 

       //set news properties 
       foreach (Models.News news in lstNewsItem) 
       { 

        news.UserId = (Guid)member.ProviderUserKey; 
        news.Title = newsTitle; 
        news.Description = newsDescription; 
        news.EntryDate = DateTime.Now; 
        news.BeginningDate = dtBeginningDate; 
        news.EndingDate = dtEndingDate; 

       }//next 

       //update the transaction 
       dcNews.SubmitChanges(); 

       //update the news list 
       return PartialView("NewsList", this.GetNewsItems()); 

      } 

      //just to make sure everything goes as planned, 
      // catch any unhandled exceptions 
      catch (Exception ex) 
      { 
       ModelState.AddModelError("_FORM", ex); 
      }//end catch 

     }//end if valid modelstate 


     //invalid modelstate, so repopulate the viewdata and 
     //send it back 

     //the list to hold the entries 
     List<Models.News> lstErrorNewsItems = new List<Models.News>(); 

     //set the remaining error properties 
     newsError.UserId = (Guid)member.ProviderUserKey; 
     newsError.NewsID = newsID; 
     newsError.EntryDate = DateTime.Now; 

     //add the item--there will only be one 
     //but the view is expecting a list so we will 
     //treat it like one 
     lstErrorNewsItems.Add(newsError); 

     return PartialView("EditNews", lstErrorNewsItems); 

    }//end actionresult 

문제가 modelstate 오류가 발생하면 modelstate을 ViewData가 반환되지 않는 것입니다. 업데이트 대상 ID를 지정하지 않았기 때문일 수도 있습니다. 하지만 이미 하나 있기 때문에 다른 updatetargetid를 설정할 수 없습니다. 어떤 아이디어?

답변

0

좋아, 나는 그것을 알아 냈다. 응답 해 주셔서 감사합니다. 나중에 참조 할 수 있도록, 모든 콘텐츠가 들어가는 하나의 마스터 구분선을 설정해야했습니다. 그런 다음, 항상 표시되는 내용이 중요하지 않도록 updateTargetID를 해당 구분선으로 설정합니다. 실제로 이것은 지속적으로 업데이트되는 태그 만 사용하기 때문에 다른 div 태그를 설정하거나 해제하는 자바 스크립트 함수를 낭비 할 필요가 없으므로 실제로 더 쉽습니다.

5

유효성 검사 오류 및 모두로 편집 양식을 다시 표시 할 때 잘 작동해야합니다. ViewData에 Post 데이터가 채워집니다.

큰 업데이트 나는 그것을 알아낼 몇 가지 테스트를했습니다. 그리고 작업 테스트 프로젝트를 만들었습니다.

내 테스트 컨트롤러

public class TestController : Controller 
    { 
       // 
     // GET: /Test/ 
     List<TestData> data; 
     public TestController() 
     { 
      data = new List<TestData>(); 
      for (var i = 0; i < 10; i++) 
      { 
       data.Add(new TestData(){Name=string.Format("TestData{0}",i.ToString().PadLeft(4,'0'))}); 
      } 
     } 

     public ActionResult Index() 
     { 


      return View(data); 
     } 

     public ActionResult Edit(string name) 
     { 
      if (Request.IsAjaxRequest()) 
      { 
       return PartialView("AjaxEdit", new TestData() { Name = name }); 
      } 

      return View(new TestData() { Name = name }); 
     } 

     [AcceptVerbs(HttpVerbs.Post)] 
     public ActionResult Edit(TestData testData) 
     { 
      ModelState.AddModelError("name", "incorrect name"); 
      if (!ModelState.IsValid) 
      { 
       if (Request.IsAjaxRequest()) 
       { 
        return PartialView("AjaxEdit"); 
       } 


      } 

      return View(); 
     } 
    } 

내보기 편집 : 는 여기에 몇 가지 목록입니다

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<AjaxValidationPartial.Models.TestData>" %> 

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> 
    Edit 
</asp:Content> 

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> 

    <h2>Edit</h2> 
    <div id="editForm"> 
<% Html.RenderPartial("AjaxEdit",Model);%> 
</div> 
</asp:Content> 

내 아약스 부분 편집보기

"%>

<%= Html.ValidationSummary("Edit was unsuccessful. Please correct the errors and try again.") %> 

<% using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "editForm" })) 
    {%> 

    <fieldset> 
     <legend>Fields</legend> 
     <p> 
      <label for="Name">Name:</label> 
      <%= Html.TextBox("Name")%> 
      <%= Html.ValidationMessage("Name", "*")%> 
     </p> 
     <p> 
      <input type="submit" value="Save" /> 
     </p> 
    </fieldset> 

<% } %> 

<div> 
    <%=Html.ActionLink("Back to List", "Index") %> 
</div> 

그리고 그것은 당신이 원하는대로 작동이 코드 내 TestData 사용 모델 클래스

public class TestData 
    { 
     public string Name { get; set; } 
    } 

. "Post"편집 동작에서 일부 모델을 부분보기로 전달하지 않는다는 것을 알아 두십시오. 렌더 된 뷰는 포스트 요청에서 필요한 모든 값을 가져옵니다.

+1

감사합니다. 나는 이것을 시도했지만 문제는 "return PartialView"가 페이지에 표시되지 않는 새 인스턴스를 반환한다고 생각한다는 것이다. 어떻게 표시 할 수 있습니까? – Austin

+0

감사! 이 작동하지만 여전히 문제가 - updatetargetid 변경 내 이전 updatetargetid 나누기. 양식 제출이 유효하면 "newsTable"의 updatetargetid를 사용하여 뉴스 항목을 다시 표시하고 싶습니다. 여러 개의 Target ID를 가질 방법이 없습니다. – Austin

관련 문제