在不同选项卡中一次打​​开多个记录时编辑ASP .NET MVC时覆盖 -

时间:2016-11-20 20:43:23

标签: c# asp.net asp.net-mvc asp.net-mvc-4

我的自定义MVC Web应用程序有一个最重要的问题。我有自定义编辑页面和imdditing大学教师,所以他们都有个人资料图片。这是我的编辑控制器,它加载视图。

public ActionResult Edit(int? id)
        {
            if (cf.CheckDBConnection() != true)
            {
                return View("~/Views/Error/NoDBConnection.cshtml");
            }

            if (checksession.CheckSessionState() != 1)
            {
                return View("~/Views/Error/NotAdmin.cshtml");
            }
            if (id == null)
            {
                return View("~/Views/Error/BadRequest.cshtml");
            }

            var disciplina = db.tblDisciplines.ToList();
            ViewBag.disciplina = disciplina;
            var specialies = db.tblSpecialities.ToList();
            ViewBag.specialty = specialies;

            var Ischecked = db.tblTeachersDisciplines.Where(p => p.TeacherID == id).Select(p => p.DisciplineID).ToArray();
            ViewBag.Checked = Ischecked;


            tblTeacher tblTeacher = db.tblTeachers.Find(id);
            var IscheckedSpec = db.tblTeachersSpecialities.Where(p => p.TeacherID == tblTeacher.ID).Select(p => p.SpecialityID).ToArray();
            ViewBag.CheckedSpec = IscheckedSpec;
            TempData["Photo"] = tblTeacher.ProfilePicture;
            if (tblTeacher == null)
            {
                return View("~/Views/Error/NotFound.cshtml");
            }

            var department = tblTeacher.TDepartment;
            ViewBag.department = department;

            return View(tblTeacher);
        }

这是点击“保存”后运行的控制器

  [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include = "ID,FirstName,SecondName,Title,PersonalCabinet,Laboratory,TelNum,Email,VisitingHours,PersonalInterests,TDepartment,ProfilePicture")] tblTeacher tblTeacher, HttpPostedFileBase file, int[] discipline, int[] specialty, string department)
        {
            var disciplina = db.tblDisciplines.ToList();
            ViewBag.disciplina = disciplina;
            var specialies = db.tblSpecialities.ToList();
            ViewBag.specialty = specialies;

            var Ischecked = db.tblTeachersDisciplines.Where(p => p.TeacherID == tblTeacher.ID).Select(p => p.DisciplineID).ToArray();
            ViewBag.Checked = Ischecked;

            var IscheckedSpec = db.tblTeachersSpecialities.Where(p => p.TeacherID == tblTeacher.ID).Select(p => p.SpecialityID).ToArray();
            ViewBag.CheckedSpec = IscheckedSpec;

            tblTeacher.TDepartment = department;
            if (department == null ||  department == "")
            {
                ModelState.AddModelError("", "Изберете факултет");
                return View(tblTeacher);
            }

            if (!ModelState.IsValid)
            {
                return View(tblTeacher);
            }
            if (discipline == null)
            {
                ModelState.AddModelError(string.Empty, "Моля, изберете дисциплини");
                return View(tblTeacher);
            }
            if (specialty == null)
            {
                ModelState.AddModelError(string.Empty, "Моля, изберете специалност");
                return View(tblTeacher);
            }            

            try
            {
                var _photo = TempData["Photo"];

                if (file != null)
                {
                    if (file.ContentLength > 0 && file.ContentLength < 1000000 && file.ContentType == "image/jpeg")
                    {
                        byte[] imageBytes = null;
                        BinaryReader reader = new BinaryReader(file.InputStream);
                        imageBytes = reader.ReadBytes((int)file.ContentLength);
                        _photo = imageBytes;
                    }
                    else
                    {
                        ModelState.AddModelError(string.Empty, "Профилната снимка е задължителна и трябва да отговаря на описаните условия!");
                        return View(tblTeacher);
                    }
                }

                tblTeacher.ProfilePicture = (byte[])_photo;
                db.Entry(tblTeacher).State = EntityState.Modified;
                db.tblTeachersDisciplines.Where(p => p.TeacherID == tblTeacher.ID).ToList().ForEach(p => db.tblTeachersDisciplines.Remove(p));
                db.tblTeachersSpecialities.Where(p => p.TeacherID == tblTeacher.ID).ToList().ForEach(p => db.tblTeachersSpecialities.Remove(p));
                db.SaveChanges();

                for (int i = 0; i < discipline.Length; i++)
                {
                    using (RSEntities entities = new RSEntities())
                    {
                        tblTeachersDiscipline TD = new tblTeachersDiscipline
                        {
                            TeacherID = tblTeacher.ID,
                            DisciplineID = discipline[i]
                        };
                        entities.tblTeachersDisciplines.Add(TD);
                        entities.SaveChanges();
                    }
                }
                for (int i = 0; i < specialty.Length; i++)
                {
                    using (RSEntities entities = new RSEntities())
                    {
                        tblTeachersSpeciality TS = new tblTeachersSpeciality
                        {
                            TeacherID = tblTeacher.ID,
                            SpecialityID = specialty[i],
                        };
                        entities.tblTeachersSpecialities.Add(TS);
                        entities.SaveChanges();
                    }
                }

                return RedirectToAction("Index");
            }

            catch (Exception ex)
            {
                DateTime currentTime = DateTime.Now;
                string _error = ex.ToString();
                _error = currentTime + " Exception: " + _error;
                SendMailOnErrorService mail = new SendMailOnErrorService();
                mail.Sendemail(_error);
                return View("~/Views/Error/DataBaseError.cshtml");
            }


        }

在当前场景中似乎出现了问题: 当我打开许多“编辑”选项卡并保存所有选项卡时,他们都会更改自己的个人资料图片,并打开最后一个选项卡。 我认为这个问题来自TempData["Photo"] = tblTeacher.ProfilePicture; 因为它可能会从最后一个选项卡中打开图片,然后当我保存一个选项卡时,它会将其应用到当前教师配置文件中。 我使用TempData["Photo"] = tblTeacher.ProfilePicture;因为如果我没有,当我编辑 - 保存配置文件时,它会从数据库中删除profilepicture,因为它从视图中显示为null,而代表它的控制器在数据库的列中插入null。 / p>

其中一个解决方案可能根本就没有使用TempData,但我想知道的是问题出现的原因以及在使用TempData时如何解决它

PS - 我已经完成了一些测试,并且100%确定问题出在TempData

1 个答案:

答案 0 :(得分:0)

您用于TempData的密钥字符串是“Photo”。从TempData为键“Photo”返回的值是您在HttpGet Edit方法中最后设置的值。如果您打开了多个“编辑”标签,则TempData["Photo"]的值将是您上次为“编辑”标签打开时设置的值。

如果您想为每个打开的“编辑”标签使用TempData,则每个“编辑”标签都需要一个唯一的密钥,如下所示:

  1. 编辑标签1:TempData [“EditTab1_Photo”]
  2. 编辑标签2:TempData [“EditTab2_Photo”]
  3. 等等。

    每个编辑视图请求的唯一TempData键并不容易,您必须为每个HTTP请求生成唯一的TempData键,并以某种方式知道在HttpPost编辑HTTP请求中使用哪个键。这是具有挑战性和过于复杂的解决方案。

    您的View没有ViewModel,这就是您所需要的,您应该立即停止使用TempData,请参阅下面的TempData用途。

    解决此问题的方法是标准的ViewModel,它是如何在View和Controller之间完成MVC数据共享的核心租户。一个教师ViewModel,在其他属性中具有byte Photo {get;set;}属性,在类型和名称中大多为1到1作为tblTeacher实体,因此该教师ViewModel的唯一实例将是传递的内容来回打开每个打开的编辑选项卡。

    目前,您正在将数据实体(tblTeacher)直接发送到View,这在MVC设计模式中并不正确。您的View不应该依赖于持久性(数据库)实体结构/表示,这种结构将来会发生变化,当发生这种情况时,它不应该破坏您的View,您的View应该依赖于将您的实体转换为结构的ViewModel特定于View,控制器负责在HTTP请求之间来回转换/映射实体和ViewModel的结构。

    关于TempData用于什么的引用文章:

    另一方面,“TempData专门用于处理HTTP重定向上的数据,因此在使用TempData时请务必谨慎。”

    http://rachelappel.com/when-to-use-viewbag-viewdata-or-tempdata-in-asp-net-mvc-3-applications/