Asp.net mvc Net MVC-如果';保存';在包含多个表单的视图中,对数据的访问失败
我有一个页面,允许用户编辑联系人的详细信息。它显示基本详细信息(姓名、地址等)、已知电子邮件地址列表和电话号码列表,并允许他们添加/编辑电子邮件和电话详细信息。我的视图有三种形式,一种用于基本详细信息,一种用于电子邮件详细信息,另一种用于电话详细信息-每种形式都会发布到不同的控制器操作(SaveDetails、SaveEmail、SavePhone)。问题是,如果用户要添加一封新电子邮件,而ModelState无效,那么一旦我返回到main Details(HttpGet)controller方法以显示页面和ModelState错误,那么我就丢失了用户在电子邮件表单中输入的数据 我真的不希望有一个包含所有细节的大表单,我希望避免使用TempData将表单输入存储/传递回主页-有人对如何实现这一点有任何建议吗 以下是我的视图模型ContactDetailsViewModel,其中包含EmailDetailsViewModel和TelephoneFaxDetailsViewModel:Asp.net mvc Net MVC-如果';保存';在包含多个表单的视图中,对数据的访问失败,asp.net-mvc,forms,save,Asp.net Mvc,Forms,Save,我有一个页面,允许用户编辑联系人的详细信息。它显示基本详细信息(姓名、地址等)、已知电子邮件地址列表和电话号码列表,并允许他们添加/编辑电子邮件和电话详细信息。我的视图有三种形式,一种用于基本详细信息,一种用于电子邮件详细信息,另一种用于电话详细信息-每种形式都会发布到不同的控制器操作(SaveDetails、SaveEmail、SavePhone)。问题是,如果用户要添加一封新电子邮件,而ModelState无效,那么一旦我返回到main Details(HttpGet)controller方
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; }
}
<%@ 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>
因此,我的想法是,如果我将整个ContactViewModel放入电子邮件帖子中,那么如果该模型无效,那么我应该能够返回整个详细信息ContactViewModel,其中将包含用户刚刚输入的基本联系人详细信息和电子邮件详细信息,这样他们就不会丢失数据。电子邮件详细信息会传递给控制器,但是当传递给控制器时,所有基本联系数据都是空的-有什么想法吗?依我看,这在您的情况下是不可行的,我的意思是,当您发布第二个表单(EmailDetails)时,您只发布该表单,所以它的范围内有什么,它只进入服务器
因此,在这种情况下,您可以选择使用Ajax来保存/验证单个字段集(电子邮件、所有电话/传真详细信息)或单个ascx。恐怕您的选项有限:
- 你要么要贴一个大的 形式,这是唯一可以保留的选项 所有的价值观李>
- 或者你只能有一个 一次可以编辑其中的一个。但是 强制用户发布三次 这可能不是你想要的
public class ContactDetailsViewModel
{
public ContactDetails Basics { get; set; }
public EmailDetails Email { get; set; }
public PhoneDetails Phone { get; set; }
}
然后可以为每个特性创建局部视图。或自定义编辑器模板。这将使您的主标记更清晰。由于页面上有三个表单,如果您提交电子邮件表单(仅包含电子邮件详细信息文本框),则视图模型的其余部分将显示为空。@Colin和@JayneT-修改了答案。
public class ContactDetailsViewModel
{
public ContactDetails Basics { get; set; }
public EmailDetails Email { get; set; }
public PhoneDetails Phone { get; set; }
}