2010-12-09 1 views
2

연락처 세부 정보를 편집 할 수있는 페이지가 있습니다. 기본 세부 정보 (이름, 주소 등), 알려진 전자 메일 주소 목록 및 전화 번호 목록을 표시하고 전자 메일 및 전화 세부 정보를 추가/편집 할 수 있습니다. 내보기에는 기본 세부 정보, 전자 메일 세부 정보 및 전화 세부 정보의 세 가지 형식이 있습니다. 각각 하나는 다른 컨트롤러 작업 (SaveDetails, SaveEmail, SaveTelephone)에 게시됩니다. 문제는 사용자가 새 전자 메일을 추가하고 ModelState가 유효하지 않은 경우입니다. 그런 다음 주 정보 (HttpGet) 컨트롤러 메서드로 돌아와 페이지 및 모델 상태 오류를 표시 한 다음 사용자가 입력 한 데이터를 손실했습니다. 이메일 양식으로Asp.Net MVC - mutilple 양식을 포함하는보기에서 '저장'데이터가 실패 할 경우 양식 데이터를 다시로드하는 방법

모든 세부 정보가 포함 된 하나의 큰 양식을 갖고 싶지 않고 기본 페이지로 양식 입력을 저장/전달하는 데 TempData를 사용하지 않으려 고합니다.이를 수행하는 방법에 대한 제안 사항이 있습니까? 여기

는 EmailDetailsViewModel 및 TelephoneFaxDetailsViewModel이 포함되어 내보기 모델 ContactDetailsViewModel입니다 :

public class ContactDetailsViewModel : MasterViewModel 
{ 
    public int ContactId { get; set; } 
    public int? EmailId { get; set; } 
    public int? TelephoneFaxId { get; set; } 

    [DisplayName("First Name")] 
    [StringLength(30, ErrorMessage = "First Name cannot be more than 30 characters")] 
    public string FirstName { get; set; } 

    [DisplayName("Last Name")] 
    [StringLength(30, ErrorMessage = "Last Name cannot be more than 30 characters")] 
    public string LastName { get; set; } 

    public IList<EmailSummary> EmailSummaries { get; set; } 
    public IList<TelephoneFaxSummary> TelephoneFaxSummaries { get; set; } 

    public EmailDetailsViewModel EmailDetails { get; set; } 
    public TelephoneFaxDetailsViewModel TelFaxDetails { get; set; } 
} 

3 개 별도의 형태를 포함하고 강하게 ContactDetailsViewModel에 입력 한 내보기 :

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<SPP.Portal.ViewModels.Contacts.ContactDetailsViewModel>" %> 
<% using (Html.BeginForm("Details","Contact", FormMethod.Post)) 
    {%> 
     <%: Html.ValidationSummary() %> 
<fieldset> 
    <%: Html.HiddenFor(m => m.EmailId) %> 
    <%: Html.HiddenFor(m => m.TelephoneFaxId) %> 

    <div class="editor-field"> 
     <div class="left"> 
      <%: Html.LabelFor(model => model.FirstName) %> 
      <%: Html.TextBoxFor(model => model.FirstName)%> 
      <%: Html.ValidationMessageFor(model => model.FirstName)%> 
     </div> 
     <div class="right"> 
      <%: Html.LabelFor(model => model.LastName) %> 
      <%: Html.TextBoxFor(model => model.LastName)%> 
      <%: Html.ValidationMessageFor(model => model.LastName)%> 
     </div> 
    </div> 

    <p> 
     <input type="button" onclick="addEmail();" id="email" value="Add New Email" /> 
     <input type="button" onclick="addTelephoneFax();" id="telFax" value="Add New Telephone/Fax" /> 
     <input name="button" id="Save"type="submit" value="Save" /> 
     <input name="button" id="Return" type="submit" value="Return" /> 
    </p> 

    <% 
     } %> 
    <fieldset> 
     <legend>All Email Details</legend> 
     <table> 
      <tr> 
       <th>Edit</th> 
       <th>Email Address</th> 
       <th>Email Type</th> 
       <th>Delete</th> 
      </tr> 
      <% foreach (var emailSummary in Model.EmailSummaries) 
       { %> 
      <tr> 
       <%: Html.Hidden(emailSummary.EmailId.ToString()) %> 
       <td> 
        <a href="<%: ResolveUrl(emailSummary.EditUrl.OriginalString) %>">Edit</a> 
       </td> 
       <td> 
        <%: emailSummary.EmailAddress %> 
       </td> 
       <td> 
        <%: emailSummary.EmailType %> 
       </td> 
       <td> 
       <a href="<%: ResolveUrl(emailSummary.DeleteUrl.OriginalString) %>" class="confirmDelete">Delete</a> 
       </td> 
      </tr> 
      <% } %> 
     </table> 
    </fieldset> 

    <% using (Html.BeginForm("EmailDetails", "Contact", FormMethod.Post)) 
    {%> 
    <div id="EmailDetails"> 
    <fieldset> 
     <legend>Email</legend> 

     <%: Html.HiddenFor(m => m.EmailDetails.Id)%> 
     <%: Html.HiddenFor(m => m.EmailDetails.ContactId)%> 
     <div class="editor-field"> 
      <div class="right"> 
       <%: Html.LabelFor(m => m.EmailDetails.EmailAddress)%> 
       <%: Html.TextBoxFor(m => m.EmailDetails.EmailAddress)%> 
       <%: Html.ValidationMessageFor(model => model.EmailDetails.EmailAddress)%> 
      </div> 
     </div> 
     <div class="editor-field"> 
      <div class="left"> 
       <%: Html.LabelFor(m => m.EmailDetails.EmailType)%> 
       <%: Html.DropDownListFor(m => m.EmailDetails.EmailType, Model.EmailDetails.EmailTypeCodes)%> 
       <%: Html.ValidationMessageFor(model => model.EmailDetails.EmailType)%> 
      </div> 
     <p> 
      <input type="submit" id="EmailSave" value="Save" /> 
      <input type="submit" name="button" id="EmailCancel" value="Cancel" /> 
     </p> 
     </fieldset> 
    <% } %> 
    </div> 

    <fieldset> 
     <legend>All Telephone/Fax Details</legend> 
     <table> 
      <tr> 
       <th>Edit</th> 
       <th>Dialing Code</th> 
       <th>Telephone/Fax Number</th> 
       <th>Delete</th> 
      </tr> 
      <% foreach (var telFaxSummary in Model.TelephoneFaxSummaries) 
       { %> 
      <tr> 
       <%: Html.Hidden(telFaxSummary.TelephoneFaxId.ToString())%> 
       <td> 
        <a href="<%:ResolveUrl(telFaxSummary.EditUrl.OriginalString)%>" >Edit</a> 
       </td> 
       <td> 
        <%: telFaxSummary.DialingCode%> 
       </td> 
       <td> 
        <%: telFaxSummary.TelephoneFaxNumber%> 
       </td> 
       <td> 
        <a href="<%:ResolveUrl(telFaxSummary.DeleteUrl.OriginalString)%>" class="confirmDelete">Delete</a> 
       </td> 
      </tr> 
      <% } %> 
     </table> 
    </fieldset> 

    <% using (Html.BeginForm("TelephoneFaxDetails", "Contact", FormMethod.Post)) 
     {%> 
     <div id="TelephoneFaxDetails"> 
     <%: Html.HiddenFor(m => m.TelFaxDetails.TelephoneFaxId)%> 
     <%: Html.HiddenFor(m => m.TelFaxDetails.ContactId)%> 
     <fieldset> 
       <legend>Telephone/Fax</legend> 
     <div class="editor-field"> 
      <div id="left" class="left"> 
       <%: Html.LabelFor(m => m.TelFaxDetails.InternationalDialingCode)%> 
       <%: Html.TextBoxFor(m => m.TelFaxDetails.InternationalDialingCode)%> 
       <%: Html.ValidationMessageFor(model => model.TelFaxDetails.InternationalDialingCode)%> 
      </div> 
      <div id="middle" class="right"> 
       <%: Html.LabelFor(m => m.TelFaxDetails.TelephoneFaxNumber)%> 
       <%: Html.TextBoxFor(m => m.TelFaxDetails.TelephoneFaxNumber)%> 
       <%: Html.ValidationMessageFor(model => model.TelFaxDetails.TelephoneFaxNumber)%> 
      </div> 
     </div> 
      <p> 
       <input type="submit" id="TelephoneSave" value="Save" /> 
       <input type="submit" name="button" id="TelephoneCancel" value="Cancel" /> 
      </p> 
     </fieldset> 
    <% } %> 
    </div> 

그리고 내 컨트롤러 방법을 사용하여 새 이메일을 추가하십시오 :

[HttpPost] 
    public ActionResult EmailDetails(ContactDetailsViewModel contactViewModel) 
    { 
     var viewModel = contactViewModel.EmailDetails; 

     if (ModelState.IsValid) 
     { 
      try 
      { 
       _viewModelService.UpdateEmail(User, viewModel); 

       return RedirectToAction("Details"); 
      } 
      catch (Exception ex) 
      { 
       ModelState.AddModelError("Exception", "The Email was not updated."); 

       return RedirectToAction("Details"); 
      } 
     } 

     return View("Details", contactViewModel); 
    } 

전체 ContactViewModel을 이메일 게시물로 가져 가면 모델이 유효하지 않은 경우 기본 연락처 세부 정보 및 이메일 세부 정보가 포함 된 전체 ContactViewModel을 반환 할 수 있어야한다는 생각입니다. 사용자가 방금 입력 했으므로 데이터가 손실되지 않습니다. 전자 메일 세부 정보는 컨트롤러에 전달되지만 모든 기본 연락처 데이터는 컨트롤러에 전달 될 때 null입니다 - 어떤 아이디어입니까?

답변

1

IMO,이 시나리오는 가능한 한 실현되지 않을 것입니다. 제 2 양식 (EmailDetails)을 게시하는 경우에만 해당 양식 만 게시하므로 SCOPE 내에 어떤 것이 든 서버에만 전송됩니다.

그런 경우 Ajax가 개별 필드 세트 (전자 메일, 모든 전화/팩스 세부 정보) 또는 개별 ascx를 저장/유효성 검사하도록 선택할 수 있습니다.

+0

페이지에 세 가지 형식이 있으므로 전자 메일 양식 (전자 메일 세부 정보 텍스트 상자 만 포함)을 제출하면 나머지 뷰 모델은 null로 처리됩니다. –

+0

코드 샘플이 위에 추가되었습니다. – JayneT

+0

@Colin 및 @JayneT - 대답을 수정했습니다. – paragy

0

귀하의 옵션이 제한되어 내가 두려워 :

  • 당신에게 하나가 하나의 큰 양식을 게시 할 수 있고, 그 모든 값을 유지하는 유일한 방법입니다.
  • 또는 한 번에 개 중 하나만 편집 할 수 있습니다. 그러나 사용자가 세 번 게시하도록하려면 은 아마도 원하는 것이 아닙니다.

코드를 조금 더 멋지게 만드는 한 가지 방법은 모델을 세 가지 속성으로 재 설계하는 것입니다. '양식'당 하나씩 :

public class ContactDetailsViewModel 
{ 
    public ContactDetails Basics { get; set; } 
    public EmailDetails Email { get; set; } 
    public PhoneDetails Phone { get; set; } 
} 

각 속성에 대해 부분보기를 만들 수 있습니다. 또는 사용자 정의 편집기 템플릿. 그러면 메인 마크 업을 조금 더 깨끗하게 유지할 수 있습니다.

관련 문제