DropDowns中的值不保存预先存在的值

时间:2015-03-20 16:06:56

标签: c# asp.net-mvc razor

我正在处理某个页面上有大量下拉列表的MVC 5应用程序。当我第一次创建记录时,所有信息都存在。但是,如果我编辑记录,即使页面显示当前有效信息,一旦保存记录,信息就会消失。我调试了post控制器操作,看来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"); }
    }
}

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

public class EditPlannerRequestViewModel     {         public int Id {get;组; }

    [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正在获取正确的帖子数据,当我走到automapper线时,一切都是两者都是正确的。但是,一旦我通过db.Entry(plannerRequest).State=EntityState.Modified行,我的信息就会被删除,但只会在外键行上。如果我将黄色箭头拖回到方法的顶部并再次单步执行,它将替换最初删除的信息。

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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

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;}