2011-04-30 50 views
5

我有幾乎完全相同的場景,由Nathon Taylor在ASP.NET MVC - Sharing Session State Between Controllers中描述。問題是,如果我將路徑保存到Session變量中的圖像List<string>它不會在ItemController中定義,所以所有的路徑都將丟失......這是我的設置:控制器和操作方法之間丟失的會話變量

Inside ImageController我有上傳()操作方法:

public ActionResult Upload() 
    { 
     var newFile = System.Web.HttpContext.Current.Request.Files["Filedata"]; 
     string guid = Guid.NewGuid() + newFile.FileName; 
     string itemImagesFolder = Server.MapPath(Url.Content("~/Content/ItemImages/")); 
     string fileName = itemImagesFolder + "originals/" + guid; 
     newFile.SaveAs(fileName); 

     var resizePath = itemImagesFolder + "temp/"; 
     string finalPath; 
     foreach (var dim in _dimensions) 
     { 
      var resizedPath = _imageService.ResizeImage(fileName, resizePath, dim.Width + (dim.Width * 10/100), guid); 
      var bytes = _imageService.CropImage(resizedPath, dim.Width, dim.Height, 0, 0); 
      finalPath = itemImagesFolder + dim.Title + "/" + guid; 
      _imageService.SaveImage(bytes, finalPath); 
     } 
     AddToSession(guid); 
     var returnPath = Url.Content("~/Content/ItemImages/150x150/" + guid); 
     return Content(returnPath); 
    } 

    private void AddToSession(string fileName) 
    { 
     if(Session[SessionKeys.Images] == null) 
     { 
      var imageList = new List<string>(); 
      Session[SessionKeys.Images] = imageList; 
     } 
     ((List<string>)Session[SessionKeys.Images]).Add(fileName); 
    } 

內。然後我ItemController我有具有下面的代碼新建()操作方法:

 List<string> imageNames; 
     var images = new List<Image>(); 
     if (Session[SessionKeys.Images] != null) //always returns false 
     { 
      imageNames = Session[SessionKeys.Images] as List<string>; 
      int rank = 1; 
      foreach (var name in imageNames) 
      { 
       var img = new Image {Name = name, Rank = rank}; 
       images.Add(img); 
       rank++; 
      } 
     } 

好了,所以爲什麼會出現這種情況,如何解決呢?

此外,我正在考慮是否可以將ActionMethod移動到ItemController的上傳並將圖像路徑存儲在ItemController本身的List屬性中,實際上會工作嗎?請注意,圖片正在上傳並通過AJAX請求處理。然後,當用戶提交的項目報名表,所有關於與圖像沿項目的數據應保存到數據庫中...

更新:

我已經更新的代碼。另外我想我應該補充一點,我使用StructureMap作爲我的控制器因素。這可能是一個範圍界定問題嗎? StructureMap通常使用的默認範圍是什麼?

public class StructureMapDependencyResolver : IDependencyResolver 
{ 
    public StructureMapDependencyResolver(IContainer container) 
    { 
     _container = container; 
    } 

    public object GetService(Type serviceType) 
    { 
     if (serviceType.IsAbstract || serviceType.IsInterface) 
     { 
      return _container.TryGetInstance(serviceType); 
     } 
     else 
     { 
      return _container.GetInstance(serviceType); 
     } 
    } 

    public IEnumerable<object> GetServices(Type serviceType) 
    { 
     return _container.GetAllInstances<object>() 

      .Where(s => s.GetType() == serviceType); 
    } 

    private readonly IContainer _container; 
} 

我的Global.asax文件裏:

private static IContainer ConfigureStructureMap() 
    { 
     ObjectFactory.Configure(x => 
     { 
      x.For<IDatabaseFactory>().Use<EfDatabaseFactory>(); 
      x.For<IUnitOfWork>().Use<UnitOfWork>(); 
      x.For<IGenericMethodsRepository>().Use<GenericMethodsRepository>(); 
      x.For<IUserService>().Use<UsersManager>(); 
      x.For<IBiddingService>().Use<BiddingService>(); 
      x.For<ISearchService>().Use<SearchService>(); 
      x.For<IFaqService>().Use<FaqService>(); 
      x.For<IItemsService>().Use<ItemsService>(); 
      x.For<IMessagingService>().Use<MessagingService>(); 
      x.For<IStaticQueriesService>().Use<StaticQueriesService>(); 
      x.For < IImagesService<Image>>().Use<ImagesService>(); 
      x.For<ICommentingService>().Use<CommentingService>(); 
      x.For<ICategoryService>().Use<CategoryService>(); 
      x.For<IHelper>().Use<Helper>(); 
      x.For<HttpContext>().HttpContextScoped().Use(HttpContext.Current); 

      x.For(typeof(Validator<>)).Use(typeof(NullValidator<>)); 

      x.For<Validator<Rating>>().Use<RatingValidator>(); 
      x.For<Validator<TopLevelCategory>>().Use<TopLevelCategoryValidator>(); 
     }); 

     Func<Type, IValidator> validatorFactory = type => 
     { 
      var valType = typeof(Validator<>).MakeGenericType(type); 
      return (IValidator)ObjectFactory.GetInstance(valType); 
     }; 

     ObjectFactory.Configure(x => x.For<IValidationProvider>().Use(() => new ValidationProvider(validatorFactory))); 
     return ObjectFactory.Container; 
    } 

有什麼想法?

+0

你能增加一些代碼嗎?特別是你正在調用AddToSession方法的控制器?這應該不會發生,除非您從另一個線程訪問會話。 – neebz 2011-04-30 21:27:06

+0

@nEEbz:我更新了帖子。請檢查出來。 – Kassem 2011-05-01 07:10:15

回答

2

一個可能的原因是應用程序域在第一個和第二個操作之間重新啓動,並且會話存儲在內存中將丟失。如果您在兩者之間重新編譯應用程序,則可能發生這種情況。嘗試在Global.asax中的Application_StartSession_Start回調中添加斷點並查看它們是否被調用兩次。

+0

@Darin Dimitrov:我不確定這是怎麼回事......我做了你所說的,這是發生了什麼:當應用第一次啓動時,兩個回調中的斷點都被觸發了。然後當我點擊上傳圖片的按鈕時,只有Session_Start回調中的斷點被觸發。然後我上傳了另一張圖片(用戶可以在提交該項目前上傳幾張圖片),並且沒有觸發任何斷點。但最終,會話變量沒有在ItemController的Ne​​w()操作方法中定義......您怎麼看? – Kassem 2011-05-01 09:03:30

+0

@Kassem,是否在瀏覽器中啓用cookies?你可以使用FireBug檢查上傳文件時最初創建的cookie是否與請求一起傳輸給New()動作? – 2011-05-01 09:06:46

+0

@Darin Dimitrov:首先沒有cookie ......在firebug中,唯一出現的cookie是.ASPXAUTH和ASP.NET_SessionId cookie ... – Kassem 2011-05-01 09:23:06

0

你是否曾經在使用它,而不是直接在你的代碼中訪問HttpContext.Current?換句話說,在單元測試中,是否有任何地方爲了嘲笑而注入了HttpContext

如果您只是直接在您的方法中訪問它,那麼沒有理由在您的應用程序啓動時輸入x.For<HttpContext>().HttpContextScoped().Use(HttpContext.Current);。我想知道如果你將它移除它是否會開始工作。

11

我只是說這Global.asax.cs中

protected void Session_Start() 
    { 
    } 

看來,這個固定的問題。我設置了一個斷點,每個會話僅擊中一次(如預期的那樣)。

+1

這對我和MVC 4工作。 – JB06 2014-09-10 14:55:20

+1

你們有沒有想過爲什麼這會有所幫助? – Robotron 2015-02-04 14:37:24

+0

這個作品找到MVC 5以及 – Jason 2016-12-08 17:54:58