ASP.Net MVC和state -如何在双列表框中从Session更改更新数据库

本文关键字:Session 数据库 更新 列表 MVC Net state ASP | 更新日期: 2023-09-27 17:49:22

我正在研究一个双列表框系统,操作员可以为特定用户分配和删除不同的练习。对于RemoveExercises函数,我已经开始使用会话,以便RequestedExercises列表框更新所做的更改(添加和删除练习)。

目前,AddExercises函数将练习从AvailableExercises列表框添加到数据库上的RequestedExercises列表框(也称为RegimeItems),但它不会出现在RequestedExercises列表框上,直到我回到页面。

RemoveExercises函数从RequestedExercises列表框中删除了一个选定的练习,但没有对数据库进行更改。所以这两个函数只完成了我想要它们做的一半,只是方式不同。

这让我相信,由于会话状态,RequestedExercises列表框上没有显示添加的练习,而RemoveExercises没有更新其对数据库的更改。如有任何帮助,我将不胜感激。

UPDATE:在post request中将return View(model);更改为return RedirectToAction("ExerciseIndex", new { id = model2.UserID, vmodel = model2 });后,添加练习效果完美。我该如何使RemoveExercises在域对象用户上工作?

Controller.cs

    [HttpGet]
    public ActionResult ExerciseIndex(int id, UserExerciseViewModel vmodel)
    {
        User user = db.Users.Find(id);
        UserExerciseViewModel model = new UserExerciseViewModel { AvailableExercises = GetAllExercises(), RequestedExercises = ChosenExercises(user, vmodel) };
        model.UserID = user.UserID;
        Session["UserExerciseViewModel"] = model;
        return View(model);
    }
    [HttpPost]
    public ActionResult ExerciseIndex(UserExerciseViewModel model, string add, string remove, string send, int id, RegimeItem item)
    {
        UserExerciseViewModel model2 = (UserExerciseViewModel)(Session["UserExerciseViewModel"]);
        model.RequestedExercises = model2.RequestedExercises;
        model.AvailableExercises = model2.AvailableExercises;
        if (!string.IsNullOrEmpty(add))
            AddExercises(model, id);
        else if (!string.IsNullOrEmpty(remove))
            RemoveExercises(model, id);
        User user = db.Users.Find(model2.UserID);
        model2.RequestedExercises = ChosenExercises(user, model);
        user.RegimeItems = model.RequestedExercises;
        RestoreSavedState(model, user);
        return RedirectToAction("ExerciseIndex", new { id = model2.UserID, vmodel = model2 });
    )
    void RemoveExercises(UserExerciseViewModel model, int id)
    {
        var userExerciseViewModel = (UserExerciseViewModel)(Session["UserExerciseViewModel"]);
        foreach (int selected in model.RequestedSelected)
        {
            RegimeItem item = model.RequestedExercises.FirstOrDefault(i => i.RegimeItemID == selected);
            if (item != null)
            {
                model.RequestedExercises.Remove(item);
            }
        }
        db.SaveChanges();
    }
    void AddExercises(UserExerciseViewModel model, int id)
    {
        var userExerciseViewModel = (UserExerciseViewModel)(Session["UserExerciseViewModel"]);
        foreach (int selected in model.AvailableSelected)
        {
            if (model.AvailableSelected != null)
            {
                User user = db.Users.Find(id);
                user.RegimeItems.Add(new RegimeItem()
                {
                    RegimeExercise = (this.GetAllExercises().FirstOrDefault(i => i.ExerciseID == selected))
                });
            }
        }
        db.SaveChanges();
    }
    void RestoreSavedState(UserExerciseViewModel model, User user)
    {
        user.RegimeItems = this.ChosenExercises(user, model);
        if (!string.IsNullOrEmpty(model.SavedRequested))
        {
            string[] exIds = model.SavedRequested.Split(',');
            var regimeItems = ChosenExercises(user, model).Where(p => exIds.Contains(p.RegimeItemID.ToString()));
            model.RequestedExercises.AddRange(regimeItems);
        }
        db.SaveChanges();
    }
    private List<Exercise> GetAllExercises() //Gets all the data for AvailableExercises
    {
        return db.Exercises.ToList();
    }
    private List<RegimeItem> ChosenExercises(User user, UserExerciseViewModel model) //Gets all the data for RequestedExercies
    {
     return db.Users
     .Where(u => u.UserID == user.UserID)
     .SelectMany(u => u.RegimeItems)
     .ToList();
    }

模型(cs)

 public class User
    {
        public int UserID { get; set; }
        public ICollection<RegimeItem> RegimeItems { get; set; }
        public User()
        {
            this.RegimeItems = new List<RegimeItem>();
        } 
    }
    public class RegimeItem
    {
        public int RegimeItemID { get; set; }
        public Exercise RegimeExercise { get; set; }
    }

视图模型(cs)

public class UserExerciseViewModel
{
    public List<Exercise> AvailableExercises { get; set; }
    public List<RegimeItem> RequestedExercises { get; set; }
    public int? SelectedExercise { get; set; }
    public int[] AvailableSelected { get; set; }
    public int[] RequestedSelected { get; set; }
    public string SavedRequested { get; set; }
    public int UserID { get; set; }
}

视图(段只有(cshtml))

<td valign="top">
   @Html.ListBoxFor(model => model.AvailableSelected, new MultiSelectList(Model.AvailableExercises, "ExerciseID", "Name", Model.AvailableSelected))
</td>
<td valign="top">
  <input type="submit" name="add"
  id="add" value=">>" /><br />
  <input type="submit" name="remove"
  id="remove" value="<<" />
</td>
<td valign="top">
    @Html.ListBoxFor(model => model.RequestedSelected, new MultiSelectList(Model.RequestedExercises, "RegimeItemID", "RegimeExercise.Name", Model.RequestedSelected))
</td>

更新:将RemoveExercises更改为此修复了删除问题:

void RemoveExercises(UserExerciseViewModel model, int id)
{
    var userExerciseViewModel = (UserExerciseViewModel)(Session["UserExerciseViewModel"]);
    foreach (int selected in model.RequestedSelected)
    {
        if (model.RequestedSelected != null)
        {
            User user = db.Users.Find(id);
            RegimeItem item = db.RegimeItems.Find(selected);
            item.RegimeExercise = this.GetAllExercises().FirstOrDefault(i => i.ExerciseID == selected); //--this removes the regimeexercise
            user.RegimeItems.Remove(item); //deletes the user's regimeitem
            db.RegimeItems.Remove(item); //removes the regimeitem itself 
        }
    }
    db.SaveChanges();

ASP.Net MVC和state -如何在双列表框中从Session更改更新数据库

当前AddExercises函数添加来自"AvailableExercises"列表框与"requesteddexexercises"列表框(也称为"AvailableExercises")被称为regmeitems)在数据库上,但它不显示在请求练习列表框,直到我返回页面。

不会,因为你不更新你的模型,只更新用户/数据库。

void AddExercises(UserExerciseViewModel model, int id)
    {
        var userExerciseViewModel = (UserExerciseViewModel)(Session["UserExerciseViewModel"]);
        foreach (int selected in model.AvailableSelected)
        {
            if (model.AvailableSelected != null)
            {
                User user = db.Users.Find(id);
                user.RegimeItems.Add(new RegimeItem()
                {
                    RegimeExercise = (this.GetAllExercises().FirstOrDefault(i => i.ExerciseID == selected))
                });
            }
        }
        db.SaveChanges(); // db is updated but your model isn't
    }

RemoveExercises函数从的列表框,但不会对数据库。

不会,因为你只更新模型而不是用户。

 void RemoveExercises(UserExerciseViewModel model, int id)
    {
        var userExerciseViewModel = (UserExerciseViewModel)(Session["UserExerciseViewModel"]);
        foreach (int selected in model.RequestedSelected)
        {
            RegimeItem item = model.RequestedExercises.FirstOrDefault(i => i.RegimeItemID == selected);
            if (item != null)
            {
                model.RequestedExercises.Remove(item);
            }
        }
        db.SaveChanges(); // What is the point of this? You didn't alter the user?
    }

通常你在这里要做的是使AddRemove方法都在域对象User上工作,以便数据库得到适当的更新,然后而不是

return View(model)

您将重定向到您的GET操作。

   return RedirectToAction("ExerciseIndex", new { id = model2.ID, vmodel= model2 });

你通常只返回模型到视图,如果它有错误,你甚至似乎没有检查:

if (ModelState.IsValid){ ...}

还要注意如何找到用户。您在ExerciseIndex中(无条件地)执行一次,然后在Remove中再次执行。为什么不直接在ExerciseIndex的顶部做,然后传递到Remove ?