我的自定义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
答案 0 :(得分:0)
您用于TempData
的密钥字符串是“Photo”。从TempData为键“Photo”返回的值是您在HttpGet Edit方法中最后设置的值。如果您打开了多个“编辑”标签,则TempData["Photo"]
的值将是您上次为“编辑”标签打开时设置的值。
如果您想为每个打开的“编辑”标签使用TempData
,则每个“编辑”标签都需要一个唯一的密钥,如下所示:
等等。
每个编辑视图请求的唯一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
用于什么的引用文章:
http://rachelappel.com/when-to-use-viewbag-viewdata-or-tempdata-in-asp-net-mvc-3-applications/