ASP.NET MVC - 共享会话状态控制器之间 [英] ASP.NET MVC - Sharing Session State Between Controllers

查看:131
本文介绍了ASP.NET MVC - 共享会话状态控制器之间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我仍然大多与控制反转陌生的(虽然我现在正在学习一下),所以如果这是解决我的问题,只是让我知道,我会回去学习一下吧。

I am still mostly unfamiliar with Inversion of Control (although I am learning about it now) so if that is the solution to my question, just let me know and I'll get back to learning about it.

我有一双控制器,这就需要一个Session变量,自然没有什么太特殊了,因为会议是如何工作摆在首位发生,但是这让我想知道什么最干净的方式来两个独立的控制器之间共享相关的对象是。在我的具体情况我有一个UploadController和ProductController的这一起工作相互上传图像文件。作为文件由UploadController上传,有关上载的数据存储在会话。之后发生这种情况,我需要来访问ProductController的会话数据。如果我创建了包含两个控制器我就可以访问这些数据我上传信息会话变量的get / set属性,但在同一时间,我会违反各种干,更不用说创造,充其量,扑朔迷离的一个对象是由两个完全断开连接的对象共享和修改设计。

I have a pair of controllers which need to a Session variable, naturally nothing too special has happen because of how Session works in the first place, but this got me wondering what the cleanest way to share related objects between two separate controllers is. In my specific scenario I have an UploadController and a ProductController which work in conjunction with one another to upload image files. As files are uploaded by the UploadController, data about the upload is stored in the Session. After this happens I need to access that Session data in the ProductController. If I create a get/set property for the Session variable containing my upload information in both controllers I'll be able to access that data, but at the same time I'll be violating all sorts of DRY, not to mention creating a, at best, confusing design where an object is shared and modified by two completely disconnected objects.

你有什么建议?

精确上下文:

一个文件上传查看职位文件UploadController.ImageWith preVIEW(),然后在发布文件并将其复制到一个临时目录中读取。保存文件后,另一个类生产上传的图片的缩略图。给原始文件,并生成缩略图的路径,然后用JsonResult返回到一个JavaScript回调的更新表单中的页面上的一些动态内容可以是保存或取消。无论是上传的图片被保存或者被忽略,我需要移动或删除它和从临时目录生成的缩略图。为了推动这项工作,UploadController跟踪所有上传的文件和缩略图的会话保持队列对象的。

A file upload View posts a file to UploadController.ImageWithpreview(), which then reads in the posted file and copies it to a temporary directory. After saving the file, another class produces a thumbnail of the uploaded image. The path to both the original file and the generated thumbnail are then returned with a JsonResult to a javascript callback which updates some dynamic content in a form on the page which can be "Saved" or "Cancelled". Whether the uploaded image is saved or it is skipped, I need to either move or delete both it and the generated thumbnail from the temporary directory. To facilitate this, UploadController keeps track of all of the upload files and their thumbnails in a Session-maintained Queue object.

早在景观:表格填充了上传,形式回发到所选的文件被标识ProductsController类的图像生成缩略图后(目前我的文件名保存在一个隐藏字段,这是我实现是一个可怕的漏洞),然后复制出来的临时目录的一个永久位置。理想情况下,我想简单地访问我已存储在会话中的队列,这样的形式并不需要包含图像位置,因为它现在。这是我怎么也想象我的解决办法,但我会热切地听任何意见或批评。

Back in the View: after the form is populated with a generated thumbnail of the image that was uploaded, the form posts back to the ProductsController where the selected file is identified (currently I store the filename in a Hidden field, which I realize is a horrible vulnerability), and then copied out of the temp directory to a permanent location. Ideally, I would like to simply access the Queue I have stored in the Session so that the form does not need to contain the image location as it does now. This is how I have envisioned my solution, but I'll eagerly listen to any comments or criticisms.

推荐答案

一对夫妇的解决方案浮现在脑海中。你可以使用一个SessionState会级映射到请求和获取/设置信息这样(我从内存中这样做,所以这是不可能的编译,其目的是传达点):

A couple of solutions come to mind. You could use a "SessionState" class that maps into the request and gets/sets the info as such (I'm doing this from memory so this is unlikely to compile and is meant to convey the point):

internal class SessionState
{
  string ImageName
  {
    get { return HttpContext.Current.Session["ImageName"]; }
    set { HttpContext.Current.Session["ImageName"] = value; }
  }
}

然后从控制器,这样做:

And then from the controller, do something like:

  var sessionState = new SessionState();
  sessionState.ImageName = "xyz";
  /* Or */
  var imageName = sessionState.ImageName;

另外,你可以创建一个控制器扩展方法:

Alternatively, you could create a controller extension method:

public static class SessionControllerExtensions
{
  public static string GetImageName(this IController controller)
  {
    return HttpContext.Current.Session["ImageName"];
  }

  public static string SetImageName(this IController controller, string imageName)
  {
    HttpContext.Current.Session["ImageName"] = imageName;
  }
}

然后从控制器:

  this.SetImageName("xyz");
  /* or */
  var imageName = this.GetImageName();

这肯定是干的。不过,我并不特别喜欢这两种解决方案,我preFER存储尽可能少的数据,如果有的话,在会话。但是,如果你的目的是守住所有这些信息而无需加载/从其他来源识别它,这是最快的(肮脏)的方式我能想到的去做。我相当肯定有一个更优雅的解决方案,但我没有所有的信息,它是什么你想要做什么的问题域。

This is certainly DRY. That said, I don't particularly like either of these solutions as I prefer to store as little data, if any, in session. But if you're intent is to hold onto all of this information without having to load/discern it from some other source, this is the quickest (dirtiest) way I can think of to do it. I'm quite certain there's a much more elegant solution, but I don't have all of the information about what it is you're trying to do and what the problem domain is.

请记住,存储在会话信息的时候,你将不得不脱水/水化通过序列化的对象,你可能不会得到你以为你是在做这种方式的性能。

Keep in mind that when storing information in the session, you will have to dehydrate/rehydrate the objects via serialization and you may not be getting the performance you think you are from doing it this way.

希望这有助于。

编辑:为了应对更多的信息
不知道在哪里你打算部署这一点,但处理图像的实时是一个DoS攻击击中一个确保消防方式。我给你的建议如下 - 这是假设,这是面向公众的,任何人都可以上传图像:

In response to additional information Not sure on where you're looking to deploy this, but processing images "real-time" is a sure fire way to be hit with a DoS attack. My suggestion to you is as follows -- this is assuming that this is public facing and anyone can upload an image:

1)允许用户上传的图像。这个图像进入通过应用或一些服务后台处理的处理队列中。另外,该图像的名称进入用户的个人的处理队列 - 可能是数据库中的表。有关后台处理的Web应用程序的信息可以发现@ <一个href=\"http://stackoverflow.com/questions/1134615/schedule-a-job-in-hosted-web-server/1135052#1135052\">http://stackoverflow.com/questions/1134615/schedule-a-job-in-hosted-web-server/1135052#1135052

1) Allow the user to upload an image. This image goes into the processing queue for background processing by the application or some service. Additionally, the name of the image goes into the user's personal processing queue -- likely a table in the database. Information about background processing in a web app can be found @ http://stackoverflow.com/questions/1134615/schedule-a-job-in-hosted-web-server/1135052#1135052

2)处理这些图像,并同时处理,显示处理图形。你可以有一个检查正在处理图像并改掉重新加载它们每X秒的产品页面上的Ajax请求。

2) Process these images and, while processing, display a "processing graphic". You can have an ajax request on the product page that checks for images being processed and trys to reload them every X seconds.

3)当一个图像被处理,用户可以选择退出处理的假设他们的上载的图像的人。这是不是可以在产品页面(s)表示,在图像上显示或在一个单独的用户队列的观点,让他们从考虑删除的图像。

3) While an image is being "processed", the user can opt out of processing assuming they're the one that uploaded the image. This is available either on the product page(s) that display the image or on a separate "user queue" view that will allow them to remove the image from consideration.

所以,你最终获得一些更多的域对象和这些对象由队列管理。我约定的坚决拥护者了配置,使产品的图像(S)的最终目标应该是pdefined $ P $。是这样的:

So, you end up with some more domain objects and those objects are managed by the queue. I'm a strong advocate of convention over configuration so the final destination of the product image(s) should be predefined. Something like:

图像/产品/ {ID} .jpg或,如果一个集合,图像/产品/ {ID} / {}序列.JPG。

images/products/{id}.jpg or, if a collection, images/products/{id}/{sequence}.jpg.

您再也不需要知道在表单中的目的地。这对所有的图像是相同的。

You then don't need to know the destination in the form. It's the same for all images.

队列则需要知道在哪里临时图像上传,什么产品ID了。队列工人从队列弹出的项目,处理它们,并相应地将它们存储

The queue then needs to know where the temp image was uploaded and what the product id was. The queue worker pops items from the queue, processes them, and stores them accordingly.

我知道这听起​​来有点更结构化比你原来打算的,但我认为这是一个小清洁。

I know this sounds a little more "structured" than what you originally intended, but I think it's a little cleaner.

这篇关于ASP.NET MVC - 共享会话状态控制器之间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆