ASP.Net MVC and state - how to keep state between requests

陌路散爱 提交于 2019-11-27 17:26:32

It's been some time since I posted the question, which was quite colored by my little experience and knowledge of MVC. Still I received some quite useful input, that eventually led me to find a solution and also gain some insight of MVC.

What threw me off in the first place, was that you could have a controller with a strongly typed object as a parameter, like this:

public ActionResult DoSomething(MyClass myObject)...

This object originated from the same controller:

...
return View(myObject);
...

This lead me to believe that the object lived throughout these two steps, and that I somehow could expect that you could send it to the view, do something and then "magically" get it back to the controller again.

After reading up about model binding, I understood that this is of course not the case. The view is completely dead and static, and unless you store the information somewhere, it is gone.

Going back to the problem, which was selecting and uploading files from the client, and building up a list of these files to be displayed, I realized that in general there are three ways to store information between requests in MVC:

  1. You can store information in form fields in the view, and post it back to the controller later
  2. You can persist it in some kind of storage, e.g. a file or a database
  3. You can store it in server memory by acessing objects that lives throughout requests, e.g. session variables

In my case, I had basically two types of information to persist: 1. The file metadata (file name, file size etc.) 2. The file content

The "by-the-book" approach would probably be to store the metadata in form fields, and the file contents in a file or in db. But there is also another way. Since I know my files are quite small and there will be only a few of them, and this solution will never be deployed in a server farm or similar, I wanted to explore the #3 option of session variables. The files are also not interesting to persist beyond the session - they are processed and discarded, so I did not want to store them in my db.

After reading this excellent article: Accessing ASP.NET Session Data Using Dynamics

I was convinced. I simply created a sessionbag class as described in the article, and then I could do the following in my controller:

    [HttpPost]
    public ActionResult AddImportFile(HttpPostedFileBase file)
    {

        ImportDataViewModel importData = SessionBag.Current.ImportData;
        if (importData == null) importData = new ImportDataViewModel();

        if (file == null)
            return RedirectToAction("DataImport");

        if (file.ContentLength > 0)
        {
            ImportDataFile idFile = new ImportDataFile { File = file };
            importData.Files.Add(idFile);
        }

        SessionBag.Current.ImportData = importData;

        return RedirectToAction("DataImport");
    }

I am fully aware that in most cases, this would be a bad solution. But for the few kb of server memory the files occupy and with the simplicity of it all, I think it worked out very nicely for me.

The additional bonus of using the SessionBag is that if the user entered a different menu item and then came back, the list of files would still be there. This would not be the case e.g. when choosing the form fields/file storage option.

As a final remark, I realize that the SessionBag is very easy to abuse, given the simplicity of use. But if you use it for what it is meant for, namely session data, I think it can be a powerful tool.

Regarding Uploading

1) Maybe consider an AJAX uploader with HTML to allow your user to select multiple files before they are sent to the server. This BlueImp Jquery AJAX file uploader is pretty amazing with a pretty great api: Blueimp Jquery File Upload. It'll allow users to drag and drop or multi select several files and edit the file order, include/exclude etc.. Then when they are happy they can press upload to sent to your controller or upload handler for processing on the server side.

2) You could make every upload persist to the database, though you would be reloading the entire page and writing some extra view model and razor code to achieve the listing effect. This is probably not going to be responsive...

Regarding Keeping State WebForms/MVC

Keeping state between requests is somewhat black magic and voodoo. When going into ASP.NET MVC, go in it understanding that web applications communicate using request and responses. So go in embracing the web as stateless and develop from there! When your model is posted through your controller, it's gone along with any variables in the controller! However before it goes away, you can store its contents in a database for retrieval later.

Web applications cannot keep true state like desktop applications. There are many ways ajax frameworks, and some voodoo tools that people employ to simulate state in the HTTP environment. And a simulation of state is really only a false mimicry of statefulness. ASP.NET Web Forms tries to simulate state as best it can by kind of hiding the stateless nature of HTTP from the developer. You can run into a lot of headache when trying to employ your own AJAX code in tandem with Web Forms markup code and its own Ajax framework.

I'm really glad you're learning MVC

All jokes aside, if you get the MVC/HTTP/Statelessness mentality, it'll be very easy to apply the patterns to other super popular frameworks like Ruby on Rails, SpringMVC (java), Django (python), CakePHP etc... This easy transfer of knowledge will help you become a much better developer and get REALLY good at Ajax.

I'm really glad you're learning MVC 3, I've been with a few internship at some very large firms that had these crazy large ASP.NET Web Forms projects with code flying everywhere just to change a few numerical values in the database (-_-') Felt like I was using scissors to knit a baby's sock. One easy wrong move, and everything broke. It felt like developing in PHP, you come out sweating and not really sure what happened and on what line. It was almost impossible to debug and update.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!