当进入另一个操作方法时,MVC 全局变量重置为 null

MVC Global variables reseting to null when entering another action method

public class MusicController : Controller
{
    User currentUser;

    public PartialViewResult UploadMusic()
    {

        return PartialView("_UploadMusic");
    }

    [HttpPost]
    public ActionResult UploadMusic(List<HttpPostedFileBase> files)
    {
        EntityDBContext db = new EntityDBContext();
        List<Song> uploadedSongs = new List<Song>();

        foreach (var file in files)
        {
            if (file != null)
            {
                string songName = Path.GetFileName(file.FileName);
                byte[] songAsBytes = new byte[file.ContentLength];

                using (BinaryReader br = new BinaryReader(file.InputStream))
                {
                    songAsBytes = br.ReadBytes(file.ContentLength);
                }

                //Save new record in database
                Song song = new Song
                {
                    SongName = songName,
                    SongBytes = songAsBytes
                };

                uploadedSongs.Add(song);
            }
        }

        string userName = User.Identity.Name;
        currentUser = db.Users.Where(x => x.Username == userName).First();
        currentUser.UserSongs = uploadedSongs;

        return ShowSongs(currentUser.UserSongs);
    }

    public ActionResult ShowSongs(List<Song> UserSongs)
    {
        return View("ShowSongs", UserSongs);
    }

    public ActionResult Publish()
    {
        EntityDBContext db = new EntityDBContext();

        foreach (var song in currentUser.UserSongs)
        {
            if (song != null)
            {
                db.Songs.Add(song);
                db.SaveChanges();
            }
        }
        return View();
    }
}

ShowSongs 视图:

@model List<Vidafo.Models.Song>

@Html.ActionLink("Publish", "Publish")

问题

所以我在控制器的顶部声明了 currentUser。然后我在此处用这一行为它分配一个值 currentUser.UserSongs = uploadedSongs; 这工作正常但是当代码进入 Publish()currentUser.UserSongs 为空。

在分配一个值后,我需要在多个操作方法中访问 currentUser.UserSongs,但它似乎在进入另一个操作时重置为 null。

为此,您可以使用 TempData,即将值存储在 TempData 字典中。这里的一个问题是 MVC 不会在回发期间改变变量的值,即在同一控制器的不同操作期间或为此调用另一个控制器,您可以按照建议使用临时变量 TempData。

对象状态不是跨请求维护的,Web 应用程序不是这样工作的。每次向服务器发送请求时,都会创建控制器对象的 新实例 。所以任何实例级值都是新的。

为了跨请求保留信息,您需要将其保留在某处。对于像用户上下文这样的东西,会话状态是一个常见的选择。您 可能 想将它包装在一个通用的提供程序接口中,以便不将您的控制器耦合到 HTTP 上下文,但其在会话中的核心存储很简单:

HttpContext.Current.Session["someKey"] = someValue;

(您甚至可以在每次请求时从数据库中重新获取。它的性能稍差,但非常简单和健壮。)

尽管如此,不要将 ASP.NET 身份系统排除在外。 ASP.NET 非常擅长为您抽象出很多内容。您已经在此处使用它了:

string userName = User.Identity.Name;

然后您使用该值从数据库中获取用户。您 可以 扩展身份系统以存储满足您需要的自定义用户对象。但这是这个问题之外的更大范围的努力。