2011-04-30 3 views
5

Nathon Taylor가 설명한 정확히 동일한 시나리오가 ASP.NET MVC - Sharing Session State Between Controllers입니다. 문제는 세션 변수 내에서 이미지에 대한 경로를 저장하면 List<string> 모든 경로가 손실되도록 ItemController에 다시 정의되지 않는다는 것입니다. 여기 내 설정이 있습니다 :세션 변수가 컨트롤러와 동작 방법간에 손실 됨

Inside ImageController Inside Upload() 액션 메소드 :

다음
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 자체의 List 속성 안에 이미지 경로를 저장할 수 있는지 생각해 보았습니다. 실제로 작동합니까? 그러나 이미지가 업로드되고 AJAX 요청을 통해 처리됩니다.

나는 코드를 업데이트했습니다 : 사용자가 항목을 입력 양식을 제출 그런 때, 이미지와 함께 항목에 대한 모든 데이터는

는 업데이트 ... 데이터베이스에 저장해야합니다. 또한 나는 내가 컨트롤러 Factor로 StructureMap을 사용하고 있다고 덧붙여 야한다고 생각한다. 범위가 지정된 문제 일 수 있습니까? 일반적으로 StructureMap에서 사용하는 기본 범위는 무엇입니까?

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; 
    } 

어떤 생각 :

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 파일 내부

?

+0

몇 가지 코드를 추가 할 수 있습니까? 특히 AddToSession 메서드를 호출하는 컨트롤러? 다른 스레드에서 Session에 액세스하지 않는 한 이런 일이 발생하지 않아야합니다. – neebz

+0

@nEEbz : 게시물을 업데이트했습니다. 확인해주세요. – Kassem

답변

2

이유 중 하나는 첫 번째와 두 번째 작업 사이에서 응용 프로그램 도메인이 다시 시작되고 세션이 메모리에 저장되므로 세션이 손실된다는 것입니다. 응용 프로그램을 둘 사이에서 다시 컴파일하면 이런 일이 발생할 수 있습니다. Global.asax의 Application_StartSession_Start 콜백에 중단 점을 넣고 두 번 호출되는지 확인하십시오.

+0

@Darin Dimitrov : 이런 일이 일어 났는지 확신 할 수 없습니다. 나는 당신이 말한대로했고 무슨 일이 일어났습니다. 앱이 처음 시작될 때 두 콜백의 중단 점이 발생했습니다.그런 다음 이미지를 업로드하는 버튼을 클릭하면 Session_Start 콜백 내의 중단 점만 트리거됩니다. 그런 다음 다른 이미지 (사용자가 항목을 제출하기 전에 여러 이미지를 업로드 할 수 있음)를 업로드했으며 중단 점이 나타나지 않았습니다. 그러나 결국, Session 변수는 ItemController의 New() 액션 메소드 내에서 정의되지 않았습니다. 어떻게 생각하십니까? – Kassem

+0

@Kassem, 브라우저에서 쿠키가 활성화되어 있습니까? 파일을 업로드 할 때 초기에 생성 된 쿠키가 요청과 함께 New() 액션으로 전송된다면 FireBug를 검사 할 수 있습니까? –

+0

@Darin Dimitrov : 처음에는 아무 쿠키도 없었습니다 ... 방화 광에서 나타나는 유일한 쿠키는 .ASPXAUTH 및 ASP.NET_SessionId 쿠키였습니다 ... – Kassem

0

코드에서 HttpContext.Current에 직접 액세스하는 것 외에 다른 것을 사용하고 있습니까? 즉, 단위 테스트에서 조롱하기 위해 HttpContext을 주사하는 곳이 있습니까?

직접 메서드에 액세스하는 경우에는 응용 프로그램을 시작할 때 x.For<HttpContext>().HttpContextScoped().Use(HttpContext.Current); 항목을 사용할 이유가 없습니다. 나는 당신이 그것을 제거하면 그것이 작동 시작할 것이라고 궁금해.

11

난 그냥이이 문제를 해결 것으로 보인다 Global.asax.cs

protected void Session_Start() 
    { 
    } 

이 추가되었습니다. 세션 당 한 번만 실행되는 중단 점을 설정합니다 (예상대로).

+1

이것은 MVC 4에서 나에게 잘 맞았습니다. – JB06

+1

왜 이것이 도움이되는지 알아 냈습니까? – Robotron

+0

이것은 MVC 5에서도 찾을 수 있습니다. – Jason

관련 문제