【问题标题】:When updating partial View the forms content is cleaned更新部分视图时,表单内容被清除
【发布时间】:2014-02-04 10:43:09
【问题描述】:

我正在制作一个表格,用于注册用户的个人数据和工作经历。 MVC5。

我有一个由 Clients 和 JobExperiences 实体组成的模型,首先使用 EF 代码创建

在这个模型上,我创建了视图模型,就像这样。

jobExperience 的视图模型

public class JobExperienceViewModel
{
    [Required]
    [Display(Name = "Nombre Compañia")]
    public string CompanyName { get; set; }

    [Required]
    [Display(Name = "Fecha de Ingreso")]
    [DataType(DataType.Date)]
    public DateTime EntryDate { get; set; }

    [Required]
    [Display(Name = "Fecha de Retiro")]
    [DataType(DataType.Date)]
    public DateTime RetirementDate { get; set; }


    [Required]
    [Display(Name = "Cargo")]
    public string Role { get; set; }

    [Required]
    [Display(Name = "Funciones")]
    public string Functions { get; set; }

    [Required]
    [Display(Name = "Motivo de Retiro")]
    public string RetirementCause { get; set; }
}

用于保存个人数据和工作经验的简历视图模型,如下所示 公共类 ResumeViewModel {

    public ResumeViewModel(Client client, ApplicationUser user)
    {
        ...
    }


    public List<JobExperienceViewModel> JobExperienceViewModels { get; set; }

    [Display(Name = "Primer nombre")]
    public string FirstName { get; set; }

    [Display(Name = "Segundo nombre")]
    public string MiddleName { get; set; }

    [Display(Name = "Primer apellido")]
    public string LastName { get; set; }
}

我创建了一个简历控制器来编排所有这些数据

public class ResumeController : Controller
{
    #region Global Actions

    //
    // GET: /Resume/
    //This method loads the information for a given userName and loads the viewmodel and pass it to the view
    [Authorize(Roles = "Admin, Recepcionista, Orientador")]
    public ActionResult Index(string userName)
    {
        var context = new ApplicationDbContext();
        var user = (from _user in context.Users
                    where _user.UserName == userName
                    select _user).FirstOrDefault();

        Client client = new Client();
        try
        {
            client = (from _client in context.Client
                      where _client.ApplicationUserId == user.Id
                      select _client).FirstOrDefault();

        }
        catch (System.Reflection.TargetException)
        {
            client = new Client();
        }

        ResumeViewModel model;

        model = new ResumeViewModel(client, user);

        TempData["ResumeViewModel"] = model;
        return View(model);
    }

    //This method is inttended to save all resume data to persistence
    [HttpPost]
    public ActionResult Index(ResumeViewModel model)
    {
        ApplicationDbContext context = new ApplicationDbContext();
        bool exists = false;

        var client = (from _client in context.Client
                      where _client.ApplicationUserId == model.ApplicationUserId
                      select _client).FirstOrDefault();

        if (!String.IsNullOrEmpty(client.ApplicationUserId))
        {
            exists = true;
        }

        client.Address = model.Address;
        client.ArmyCard = model.ArmyCard;
        client.ArmyCardClass = model.ArmyCardClass;
        client.BasicKnowledgeCoreId = model.SelectedBasicKnowledgeCoreId;
        client.BirthCityId = model.SelectedBirthCityId;
        client.BirthCountryId = model.SelectedBirthCountryId;
        client.BirthDate = model.BirthDate;
        client.BirthDepartmentId = model.SelectedBirthDepartmentId;
        client.CellPhoneNumber = model.CellPhoneNumber;
        client.Comments = model.Comments;
        client.DataVisibilityLevelId = model.SelectedDataVisibilityLevelId;
        client.DocumentNumber = model.DocumentNumber;
        client.DocumentTypeId = model.SelectedDocumentTypeId;
        client.DrivingLicenceExpirationDate = model.DrivingLicenceExpirationDate;
        client.DrivingLicenseCategoryId = model.SelectedDrivingLicenseCategoryId;
        client.EducationCountryId = model.SelectedEducationCountryId;
        client.FirstNationalityId = model.SelectedFirstNationalityId;
        client.GenreID = model.SelectedGenreId;
        client.GraduationYear = model.GraduationYear;
        client.HandicapTypeID = model.SelectedHandicapTypeID;
        client.HasWorkExperience = model.HasWorkExperience;
        client.HireTypeId = model.SelectedHireTypeId;
        client.HomeCityId = model.SelectedHomeCityId;
        client.HomeCountryId = model.SelectedHomeCountryId;
        client.HomeDepartmentId = model.SelectedHomeDepartmentId;
        client.Institution = model.Institution;
        client.IsGraduated = model.IsGraduated;
        client.IsHomeOfficeInterested = model.IsHomeOfficeInterested;
        client.IsHouseHoldHead = model.IsHouseHoldHead;
        client.LanguageId = model.SelectedLanguageId;
        client.LanguageSkillLevelID = model.SelectedLanguageSkillLevelID;
        client.MarriageStatusId = model.SelectedMarriageStatusId;
        client.Neighborhood = model.Neighborhood;
        client.PhoneNumber = model.PhoneNumber;
        client.ProCardExpeditionDate = model.ProCardExpeditionDate;
        client.ProCardNumber = model.ProCardNumber;
        client.ProfessionalCardCareer = model.ProfessionalCardCareer;
        client.ProfessionalProfile = model.ProfessionalProfile;
        client.SalaryRangeId = model.SelectedSalaryRangeId;
        //Este campo está comentadoporque el proceso de registro debe hacerse por detalles del nivel, donde esta elid y sus detalles.
        //client.ScholarLevelId = model.SelectedScholarLevelId;
        client.SecondNationalityId = model.SelectedSecondNationalityId;
        client.Title = model.Title;
        client.WorkStatusID = model.SelectedWorkStatusID;



        if (!exists)
        { context.Client.Add(client); }

        try
        {
            if (context.SaveChanges() > 0)
                RedirectToAction("Index", "SearchClient");
            else { return View(model); }
        }
        catch (Exception)
        {
            return View(model);
            throw;
        }

        return View(model);
    }

    #endregion

    #region JobExperience


    public ActionResult ShowJobExperience(ICollection<Models.JobExperienceViewModel> JobExperienceViewModels)
    {   
        return View(JobExperienceViewModels);
    }

    public ActionResult CreateJobExperience(ICollection<Models.JobExperienceViewModel> JobExperienceViewModels)
    {
        return View(JobExperienceViewModels);
    }

    [HttpGet]
    public ActionResult CreateJobExperience(Models.JobExperienceViewModel JobExperienceViewModel)
    {
        #region Using TempData

        ResumeViewModel model = (ResumeViewModel)TempData["ResumeViewModel"];

        model.JobExperienceViewModels.Add(JobExperienceViewModel);

        TempData["ResumeViewModel"] = model;

        #endregion

        return View("Index", model);
    }

    #endregion
}

最后以这种方式组织视图。包含所有个人数据的父视图,以及 jobExperiences 列表并将视图创建为大表单中的部分视图。

视图的一些相关部分是

@model CAEWebSite.Models.ResumeViewModel

@{
    ViewBag.Title = "Hoja de Vida";
}

@using (Ajax.BeginForm(null))
{
@Html.AntiForgeryToken()

<div class="form-horizontal">
    <h4>
        @{var fullName = Model.FirstName +
                  (!String.IsNullOrWhiteSpace(Model.MiddleName) ? " " + Model.MiddleName : String.Empty) +
                  (!String.IsNullOrWhiteSpace(Model.LastName) ? " " + Model.LastName : String.Empty) +
                  (!String.IsNullOrWhiteSpace(Model.SecondLastName) ? " " + Model.SecondLastName : String.Empty);
        }
        @fullName
    </h4>
    <hr />
    @Html.ValidationSummary(true)

    <div class="form-group">
        <div class="col-md-12">
            @Model.Email
        </div>
    </div>

    <div class="form-group">
        <div class="col-md-12">
            @Model.UserName
        </div>
    </div>
    <hr />
    <h3>Datos personales</h3>
    <div class="form-group">
        @Html.LabelFor(model => model.BirthDate, new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.TextBoxFor(model => model.BirthDate, new { @type = "date" })

            @Html.ValidationMessageFor(model => model.BirthDate)
        </div>
    </div>

    <h3>Experiencia laboral</h3>
    <div class="form-group">
        @Html.LabelFor(model => model.HasWorkExperience, new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.HasWorkExperience)
            @Html.ValidationMessageFor(model => model.HasWorkExperience)
        </div>
    </div>
    <h3>Trabajos anteriores</h3>
    <div class="col-md-12">
        <div id="divListJobExperience">
            @Html.Partial("_ListJobExperience", Model.JobExperienceViewModels)
        </div>
        <p>
            @*@Html.Action("ShowJobExperience", Model.JobExperienceViewModels)*@
            <a href="#" onclick="$('#newJobExperience').bPopup({}); return false;">Nueva experiencia</a>
        </p>
    </div>

<div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>
</div>

}

<div id="newJobExperience" style="background-color:#fff; border-radius:5px;">
<div class="col-md-12">
    @Html.Partial("_CreateJobExperience", new CAEWebSite.Models.JobExperienceViewModel())
</div>
</div>

</div>

@section Scripts {
@Scripts.Render("~/bundles/jqueryval")

<script>
    $("#newJobExperience").hide();
    $("#newRelative").hide();
    $("#newCapacitationCourse").hide();
    $("#newScholarLevelDetail").hide();
</script>

}

@Html.Partial("_CreateJobExperience", new CAEWebSite.Models.JobExperienceViewModel())

部分视图以模式加载 bpopup 插件。部分视图是这样的

_ListJobExperience 视图

@model IEnumerable<CAEWebSite.Models.JobExperienceViewModel>


<table class="table">
<tr>
    <th>
        @Html.DisplayNameFor(model => model.CompanyName)
    </th>
    <th>
        @Html.DisplayNameFor(model => model.EntryDate)
    </th>
    <th>
        @Html.DisplayNameFor(model => model.RetirementDate)
    </th>
    <th>
        @Html.DisplayNameFor(model => model.Role)
    </th>
    <th>
        @Html.DisplayNameFor(model => model.Functions)
    </th>
    <th>
        @Html.DisplayNameFor(model => model.RetirementCause)
    </th>
    <th></th>
</tr>

@foreach (var item in Model)
{
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.CompanyName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.EntryDate)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.RetirementDate)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Role)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Functions)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.RetirementCause)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
            @Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
            @Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
        </td>
    </tr>
}

</table>

_CreateJobExperience 视图

public class ResumeController : Controller
{
    #region Global Actions

    //
    // GET: /Resume/
    [Authorize(Roles = "Admin, Recepcionista, Orientador")]
    public ActionResult Index(string userName)
    {
        var context = new ApplicationDbContext();
        var user = (from _user in context.Users
                    where _user.UserName == userName
                    select _user).FirstOrDefault();

        Client client = new Client();
        try
        {
            client = (from _client in context.Client
                      where _client.ApplicationUserId == user.Id
                      select _client).FirstOrDefault();

        }
        catch (System.Reflection.TargetException)
        {
            client = new Client();
        }

        ResumeViewModel model;

        model = new ResumeViewModel(client, user);

        TempData["ResumeViewModel"] = model;
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(ResumeViewModel model)
    {
        ApplicationDbContext context = new ApplicationDbContext();
        bool exists = false;

        var client = (from _client in context.Client
                      where _client.ApplicationUserId == model.ApplicationUserId
                      select _client).FirstOrDefault();

        if (!String.IsNullOrEmpty(client.ApplicationUserId))
        {
            exists = true;
        }

        client.Address = model.Address;
        client.ArmyCard = model.ArmyCard;
        client.ArmyCardClass = model.ArmyCardClass;
        client.BasicKnowledgeCoreId = model.SelectedBasicKnowledgeCoreId;
        client.BirthCityId = model.SelectedBirthCityId;
        client.BirthCountryId = model.SelectedBirthCountryId;
        client.BirthDate = model.BirthDate;
        client.BirthDepartmentId = model.SelectedBirthDepartmentId;
        client.CellPhoneNumber = model.CellPhoneNumber;
        client.Comments = model.Comments;
        client.DataVisibilityLevelId = model.SelectedDataVisibilityLevelId;
        client.DocumentNumber = model.DocumentNumber;
        client.DocumentTypeId = model.SelectedDocumentTypeId;
        client.DrivingLicenceExpirationDate = model.DrivingLicenceExpirationDate;
        client.DrivingLicenseCategoryId = model.SelectedDrivingLicenseCategoryId;
        client.EducationCountryId = model.SelectedEducationCountryId;
        client.FirstNationalityId = model.SelectedFirstNationalityId;
        client.GenreID = model.SelectedGenreId;
        client.GraduationYear = model.GraduationYear;
        client.HandicapTypeID = model.SelectedHandicapTypeID;
        client.HasWorkExperience = model.HasWorkExperience;
        client.HireTypeId = model.SelectedHireTypeId;
        client.HomeCityId = model.SelectedHomeCityId;
        client.HomeCountryId = model.SelectedHomeCountryId;
        client.HomeDepartmentId = model.SelectedHomeDepartmentId;
        client.Institution = model.Institution;
        client.IsGraduated = model.IsGraduated;
        client.IsHomeOfficeInterested = model.IsHomeOfficeInterested;
        client.IsHouseHoldHead = model.IsHouseHoldHead;
        client.LanguageId = model.SelectedLanguageId;
        client.LanguageSkillLevelID = model.SelectedLanguageSkillLevelID;
        client.MarriageStatusId = model.SelectedMarriageStatusId;
        client.Neighborhood = model.Neighborhood;
        client.PhoneNumber = model.PhoneNumber;
        client.ProCardExpeditionDate = model.ProCardExpeditionDate;
        client.ProCardNumber = model.ProCardNumber;
        client.ProfessionalCardCareer = model.ProfessionalCardCareer;
        client.ProfessionalProfile = model.ProfessionalProfile;
        client.SalaryRangeId = model.SelectedSalaryRangeId;
        //Este campo está comentadoporque el proceso de registro debe hacerse por detalles del nivel, donde esta elid y sus detalles.
        //client.ScholarLevelId = model.SelectedScholarLevelId;
        client.SecondNationalityId = model.SelectedSecondNationalityId;
        client.Title = model.Title;
        client.WorkStatusID = model.SelectedWorkStatusID;



        if (!exists)
        { context.Client.Add(client); }

        try
        {
            if (context.SaveChanges() > 0)
                RedirectToAction("Index", "SearchClient");
            else { return View(model); }
        }
        catch (Exception)
        {
            return View(model);
            throw;
        }

        return View(model);
    }

    #endregion

    #region JobExperience


    public ActionResult ShowJobExperience(ICollection<Models.JobExperienceViewModel> JobExperienceViewModels)
    {   
        return View(JobExperienceViewModels);
    }

    public ActionResult CreateJobExperience(ICollection<Models.JobExperienceViewModel> JobExperienceViewModels)
    {
        return View(JobExperienceViewModels);
    }

    [HttpPost]
    public ActionResult CreateJobExperience(Models.JobExperienceViewModel JobExperienceViewModel)
    {
        #region Using TempData

        ResumeViewModel model = (ResumeViewModel)TempData["ResumeViewModel"];

        model.JobExperienceViewModels.Add(JobExperienceViewModel);

        TempData["ResumeViewModel"] = model;

        #endregion

        return View("Index", model);
    }

    #endregion
}
}

问题

每当我创建新的工作体验时,我都会更新 viemodel,将 jobExperienceViewModel 添加到体验列表中,然后将其发送回要返回的视图。

而且它有效,体验列表似乎已填满。但是,表单中的所有数据都丢失了,被清除了。

我正在使用在所有用户交互期间保持视图模型状态的方法,直到他或她单击表单提交,然后我会将所有模型发送到持久性。

我认为我需要一种方法来更新体验列表,就像在老式更新面板中一样。

或者是一种让我能够涵盖该功能的解决方法。

【问题讨论】:

    标签: c# .net razor asp.net-mvc-5 asp.net-mvc-partialview


    【解决方案1】:

    在这里,您将使用 Ajax 表单提交劳动经验,而无需清理“主要表单”中的数据:

    型号:

        public class HojaDeVida
    {
        public HojaDeVida()
        {
            ExperienciasLaborales = new List<ExperienciaLaboral>();
        }
    
        public string Nombre { get; set; }
        public string Apellido { get; set; }
        public IList<ExperienciaLaboral> ExperienciasLaborales { get; set; }
    }
    
    public class ExperienciaLaboral
    {
        public string Empresa { get; set; }
        public int Anios { get; set; }
    }
    

    控制器:

        public class HomeController : Controller
    {
        [HttpGet]
        public ActionResult Index()
        {
            TempData["hojavida"] = new HojaDeVida();
            return View();
        }
    
        [HttpPost]
        public ActionResult Index(HojaDeVida hojaDeVida)
        {
             //Submit the info in "hojaDeVida" and TempData["HojaVida"]
            return new EmptyResult();
        }
    
        [HttpPost]
        public PartialViewResult AddExperienciaLaboral(ExperienciaLaboral experiencia)
        {
            var hojadevida = (HojaDeVida)TempData["hojavida"];
            hojadevida.ExperienciasLaborales.Add(experiencia);
            TempData["hojavida"] = hojadevida;
            return PartialView("_ListExperiencias", hojadevida.ExperienciasLaborales);
        }
    }
    

    “主要观点”(Hoja de Vida):

    @using WebApplication1.Controllers
    @model HojaDeVida
    @{
        ViewBag.Title = "Home Page";
    }
    
    @using (Html.BeginForm("Index", "Home"))
        {
            <div>
                @Html.LabelFor(x => x.Nombre)
                @Html.EditorFor(x => x.Nombre)
            </div>
            <div>
                @Html.LabelFor(x => x.Apellido)
                @Html.EditorFor(x => x.Apellido)
            </div>
            <input type="submit" value="Guardar Hoja de Vida" />
        }
    
    @Html.Partial("_AddExperiencia", new ExperienciaLaboral())
    
    @section scripts
    {
        @Scripts.Render("~/Scripts/jquery.unobtrusive-ajax.min.js")
    }
    

    然后是“_AddExperience”PartialView,带有一个 Ajax 表单:

    @using WebApplication1.Controllers
    @model ExperienciaLaboral
    @using (Ajax.BeginForm("AddExperienciaLaboral", "Home", new AjaxOptions { UpdateTargetId = "data", HttpMethod = "POST" }))
        {
            <div>
                @Html.LabelFor(x => Model.Empresa)
                @Html.EditorFor(x => Model.Empresa)
            </div>
            <div>
                @Html.LabelFor(x => Model.Anios)
                @Html.EditorFor(x => Model.Anios)
            </div>
            <input type="submit" value="Agregar Experiencia" />
        }
    <div id="data">
        @Html.Partial("_ListExperiencias", new List<ExperienciaLaboral>())
    </div>
    

    最后是“_ListExperiencias”PartialView:

    @model IList<WebApplication1.Controllers.ExperienciaLaboral>
    @foreach (var item in Model)
        {
            <div>
                @string.Format("Empresa : {0} | Años: {1}", item.Empresa, item.Anios)
        </div>
        }
    

    如您所见,Ajax 表单位于 HTML 表单 you can't nested two forms(此处为 Ajax 表单和 HTML 表单)之外,您需要使用一些 JavaScript 或 jQuery.Ajax 才能嵌套漂亮的可视化表单

    【讨论】:

    • 我无法让它工作,它会在浏览器中单独打开部分视图,而不是在我正在处理的页面中
    • 你需要从 NuGet 安装jquery.unobtrusive-ajax.min.js
    【解决方案2】:

    您可以使用 ajax + web api 或控制器中的任何操作来保存体验。

    【讨论】:

    • 你能再开发一点吗?我尝试对控制器进行 ajax 调用,但出现了这个错误,因为,谁知道为什么,系统试图找到一个不存在的 CreateJobExperience 视图,因为这是一个名为 _CreateJobExperience 的局部视图
    猜你喜欢
    • 2011-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-19
    相关资源
    最近更新 更多