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();
}
}
显示歌曲视图:
@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。
static
static User currentUser;