MVC全局变量在输入另一个操作方法时重置为null
本文关键字:null 操作方法 全局变量 输入 另一个 MVC | 更新日期: 2023-09-27 18:00:15
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。
对象状态不是跨请求维护的,这不是web应用程序的工作方式。每次向服务器发送请求时,都会创建控制器对象的新实例。因此,任何实例级别的值都是新的。
为了在请求之间持久化信息,您需要将其持久化到某个地方。对于类似于用户上下文的东西,会话状态是一个常见的选择。您可能想要将其封装在一个通用的提供者接口中,这样就不会将控制器耦合到HTTP上下文,但其核心存储在会话中很简单:
HttpContext.Current.Session["someKey"] = someValue;
(您甚至可以在每次请求时从数据库中重新获取。它的性能稍差,但非常简单和健壮。(
不要把ASP计算在内。NET标识系统。ASP。NET非常擅长为您抽象其中的许多内容。你已经在这里使用了:
string userName = User.Identity.Name;
然后使用该值从数据库中获取用户。您可以扩展身份系统以存储符合您需求的自定义用户对象。但这是一个超出这个问题范围的更大范围的努力。
为此,您可以使用TempData,即将值存储在TempData字典中。这里的一个问题是MVC在回发期间不会改变变量的值,即在同一控制器的不同操作或为此调用另一个控制器期间,您可以按照建议使用临时变量TempData。