【问题标题】:Values in DropDowns not saving pre-existing valuesDropDowns 中的值不保存预先存在的值
【发布时间】:2015-03-20 16:06:55
【问题描述】:

我正在开发一个 MVC 5 应用程序,该应用程序在某个页面上有大量下拉列表。当我第一次创建记录时,所有信息都存在。但是,如果我编辑记录,即使页面显示当前有效信息,一旦保存记录,信息就会消失。我调试了后控制器操作,似乎 ID 正在传递到数据库,但我不确定这里发生了什么。

这是我受影响页面的模型。

[Table("facility.PlannerRequest")]
public class FacilityPlannerRequest
{
    public int Id { get; set; }
    [Display(Name = "Work Type")]
    public int? WorktypeId { get; set; }
    [Display(Name = "Requestor")]
    public int? RequestorId { get; set; }
    [Display(Name = "Hardware Location")]
    public int? EquipmentLocationId { get; set; }
    [Display(Name = "Model")]
    public int? HardwareModelId { get; set; }
    [Display(Name = "Manufacturer")]
    public string FreeManufacturer { get; set; }
    [Display(Name = "Series")]
    public string FreeSeries { get; set; }
    [Display(Name = "Model")]
    public string FreeHardwareModel { get; set; }
    [Display(Name = "Cost Center")]
    public int? CostCenterId { get; set; }
    [Display(Name = "Cost Center")]
    public string FreeCostCenter { get; set; }
    [Display(Name = "Client")]
    public string ClientName { get; set; }
    [Display(Name = "RDI/WLP")]
    public string RDIWLPNumber { get; set; }
    [Display(Name = "Associated System")]
    public string AssociatedSystem { get; set; }
    [Display(Name = "Breaker Size")]
    public int? BreakerSize { get; set; }
    [Display(Name = "Number Of Poles")]
    public int? NumberOfPoles { get; set; }
    [Display(Name = "Connector Type")]
    public int? ConnectorId { get; set; }
    [Display(Name = "Connector Location")]
    public int? ConnectorLocationId { get; set; }
    public string Instructions { get; set; }
    [Display(Name = "Status")]
    public int? StatusId { get; set; }
    [Display(Name = "Work Start Date")]
    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
    public DateTime? WorkStartDate { get; set; }
    [Display(Name = "Work Comp Date")]
    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
    public DateTime? WorkCompletedDate { get; set; }
    [Display(Name = "Date Entered")]
    public DateTime? EnteredDate { get; set; }
    [Display(Name = "Last Modified")]
    public DateTime? LastModified { get; set; }

    public virtual FacilityRequestor Requestor { get; set; }
    public virtual FacilityHardwareRequestDescription WorkType { get; set; }
    public virtual FacilityLocation EquipmentLocation { get; set; }
    public virtual HardwareModel Model { get; set; }
    public virtual FacilityCostCenter CostCenter { get; set; }
    public virtual HardwareConnector Connector { get; set; }
    public virtual FacilityLocation ConnectorLocation { get; set; }
    public virtual FacilityPlannerRequestStatus PlannerRequestStatus { get; set; }

    ShopDb db = new ShopDb();
    public virtual SelectList RequestorList
    {
        get
        {
            var activeRequestors = (from r in db.FacilityRequestors
                         where !r.Deleted
                         select r).OrderBy(f => f.FacilityEmployee.FirstName); 

            return new SelectList(activeRequestors, "Id", "FullName");
        }
    }
    public virtual SelectList WorkTypeList
    {
        get { return new SelectList(db.FacilityHardwareRequestDescriptions, "Id", "WorkType"); }
    }
    public virtual SelectList ConnectorList
    {
        get { return new SelectList(db.HardwareConnectors, "Id", "Type"); }
    }
    public virtual SelectList RequestStatusList
    {
        get { return new SelectList(db.FacilityPlannerRequestStatuses, "Id", "Status"); }
    }
}

上面的模型用于创建过程,对于编辑视图模型,我使用:

公共类 EditPlannerRequestViewModel { 公共 int ID { 获取;放; }

    [Display(Name = "Requestor")]
    public int? RequestorId { get; set; }

    [Display(Name = "Work Type")]
    public int? WorktypeId { get; set; }

    [Display(Name = "Hardware Location")]
    public int? EquipmentLocationId { get; set; }

    [Display(Name = "Model")]
    public int? HardwareModelId { get; set; }

    [Display(Name = "Manufacturer")]
    public string FreeManufacturer { get; set; }

    [Display(Name = "Series")]
    public string FreeSeries { get; set; }

    [Display(Name = "Model")]
    public string FreeHardwareModel { get; set; }

    [Display(Name = "Cost Center")]
    public int? CostCenterId { get; set; }

    [Display(Name = "Cost Center")]
    public string FreeCostCenter { get; set; }

    [Display(Name = "Client")]
    public string ClientName { get; set; }

    [Display(Name = "RDI/WLP")]
    public string RDIWLPNumber { get; set; }

    [Display(Name = "Associated System")]
    public string AssociatedSystem { get; set; }

    [Display(Name = "Breaker Size")]
    public int? BreakerSize { get; set; }

    [Display(Name = "Number Of Poles")]
    public int? NumberOfPoles { get; set; }

    [Display(Name = "Connector Type")]
    public int? ConnectorId { get; set; }

    [Display(Name = "Connector Location")]
    public int? ConnectorLocationId { get; set; }

    public string Instructions { get; set; }

    [Display(Name = "Work Start Date")]
    public DateTime WorkStartDate { get; set; }

    [Display(Name = "Work Comp Date")]
    public DateTime WorkCompletedDate { get; set; }

    public virtual FacilityRequestor Requestor { get; set; }
    public virtual FacilityHardwareRequestDescription WorkType { get; set; }
    public virtual FacilityLocation EquipmentLocation { get; set; }
    public virtual HardwareModel Model { get; set; }
    public virtual FacilityCostCenter CostCenter { get; set; }
    public virtual HardwareConnector Connector { get; set; }
    public virtual FacilityLocation ConnectorLocation { get; set; }
    public virtual FacilityPlannerRequestStatus PlannerRequestStatus { get; set; }

    public virtual SelectList RequestorList { get; set; }
    public virtual SelectList WorkTypeList { get; set; }
    public virtual SelectList ConnectorList { get; set; }

}

对于我的控制器,我的两种编辑方法是:

    public ActionResult Edit(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        var facilityplannerrequest =
            Mapper.Map<FacilityPlannerRequest, EditPlannerRequestViewModel>(db.FacilityPlannerRequests.Find(id));
        if (facilityplannerrequest == null)
        {
            return HttpNotFound();
        }
        return View(facilityplannerrequest);
    }

    // POST: /PlannerRequests/Edit/5
    // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
    // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit([Bind(Include="Id,WorkTypeId,RequestorId,EquipmentLocationId,HardwareModelId,FreeManufacturer,FreeSeries,FreeHardwareModel,CostCenterId,FreeCostCenter,ClientName,RDIWLPNumber,AssociatedSystem,BreakerSize,NumberOfPoles,ConnectorId,ConnectorLocationId,Instructions,WorkStartDate,WorkCompletedDate")]EditPlannerRequestViewModel facilityplannerrequest)
    {
        if (ModelState.IsValid)
        {
            var plannerRequest= db.FacilityPlannerRequests.Find(facilityplannerrequest.Id);

            Mapper.Map(facilityplannerrequest, plannerRequest);
            plannerRequest.LastModified = DateTime.UtcNow;
            plannerRequest.StatusId = 1;
            db.Entry(plannerRequest).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(facilityplannerrequest);
    }

我正在使用 automapper 映射值:

        Mapper.CreateMap<FacilityPlannerRequest, EditPlannerRequestViewModel>();
        Mapper.CreateMap<EditPlannerRequestViewModel, FacilityPlannerRequest>()
            .ForMember(t=> t.EnteredDate, s=> s.Ignore())
            .ForMember(t=>t.LastModified, s=> s.Ignore())
            .ForMember(t=>t.StatusId, s=> s.Ignore())
            .ForMember(t=>t.RequestStatusList,s=>s.Ignore());


编辑

值得注意的是,如果我在 post 方法中逐行执行代码,我可以看到 facilityplannerrequest 正在获取正确的 post 数据,当我进入 automapper 行时,一切仍然正确双方。但是,一旦我通过了db.Entry(plannerRequest).State=EntityState.Modified 行,我的信息就会被删除,但仅限于外键行。如果我将黄色箭头拖回该方法的顶部并再次单步执行,它将替换它最初删除的信息。

【问题讨论】:

  • 仅供参考:使用视图模型和使用 [Bind(Include="foo")] 几乎是相互排斥的。如果您不想更新某些属性,请不要将它们包含在您的视图模型中。
  • 我很清楚,我只是添加了绑定,看看是否发生了奇怪的事情。
  • 看来和AutoMapper有关。删除视图模型后,它按预期工作

标签: c# asp.net-mvc razor


【解决方案1】:

我不确定这是否能解决您的问题,但您提到删除 AutoMapper 有所帮助。我在使用 ForMember 函数的自定义 AutoMapper 映射方面遇到了类似的问题。由于某种原因,信息被存储在某种类型的缓存或配置中​​,并且会忽略任何新的映射。我修复它的方法是在我忽略或设置标准之外的映射的任何自定义映射之前添加Mapper.Reset();。希望这会有所帮助。

【讨论】:

    【解决方案2】:

    我发现正在发生的事情与我的主模型中的虚拟成员有关。由于这些成员是外键并且是通过直接从数据库中获取信息来设置的,因此它们不能真正由自动映射器“设置”。这导致映射器保留信息的问题。一旦我调整我的视图以不再使用这些成员并随后删除它们,一切似乎都在按应有的方式运行。这些虚拟成员是:

    public virtual FacilityRequestor Requestor { get; set; }
    public virtual FacilityHardwareRequestDescription WorkType { get; set; }
    public virtual FacilityLocation EquipmentLocation { get; set; }
    public virtual FacilityCostCenter CostCenter { get; set; }
    public virtual HardwareConnector Connector { get; set; }
    public virtual FacilityLocation ConnectorLocation { get; set; }
    public virtual FacilityPlannerRequestStatus PlannerRequestStatus { get; set;}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-16
      • 2020-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多