2009-08-11 26 views
6

Tôi vẫn chưa quen với Inversion of Control (mặc dù bây giờ tôi đang học về nó) nên nếu đó là giải pháp cho câu hỏi của tôi, hãy cho tôi biết và tôi sẽ nhận được quay lại tìm hiểu về nó.ASP.NET MVC - Chia sẻ trạng thái phiên giữa các bộ điều khiển

Tôi có một bộ điều khiển cần biến Session, tự nhiên không có gì quá đặc biệt xảy ra vì Session hoạt động như thế nào ở vị trí đầu tiên, nhưng điều này khiến tôi tự hỏi cách nào để chia sẻ các đối tượng liên quan giữa hai bộ điều khiển riêng biệt Là. Trong kịch bản cụ thể của tôi, tôi có một UploadController và một ProductController mà làm việc cùng với nhau để tải lên các tập tin hình ảnh. Vì các tệp được tải lên bởi tệp UploadController, dữ liệu về tải lên được lưu trữ trong Phiên. Sau khi điều này xảy ra, tôi cần truy cập dữ liệu Session đó trong ProductController. Nếu tôi tạo thuộc tính get/set cho biến Session chứa thông tin tải lên của tôi trong cả hai bộ điều khiển, tôi sẽ có thể truy cập dữ liệu đó, nhưng đồng thời tôi sẽ vi phạm tất cả các loại DRY, chưa kể đến việc tạo, ở thiết kế tốt nhất, khó hiểu, nơi một đối tượng được chia sẻ và sửa đổi bởi hai đối tượng hoàn toàn bị ngắt kết nối.

Bạn đề xuất điều gì?

Bối cảnh chính xác:

Một tập tin tải lên Xem bài viết một tập tin vào UploadController.ImageWithpreview(), sau đó đọc trong file gửi và sao chép nó vào thư mục tạm thời. Sau khi lưu tệp, một lớp khác sẽ tạo hình thu nhỏ của hình ảnh đã tải lên. Đường dẫn tới cả tệp gốc và hình thu nhỏ được tạo ra sau đó được trả về với một JsonResult đến một cuộc gọi lại javascript để cập nhật một số nội dung động trong một biểu mẫu trên trang có thể là "Đã lưu" hoặc "Đã hủy". Cho dù hình ảnh được tải lên được lưu hay nó bị bỏ qua, tôi cần phải di chuyển hoặc xóa cả ảnh và hình thu nhỏ được tạo ra từ thư mục tạm thời. Để tạo điều kiện thuận lợi cho việc này, UploadController theo dõi tất cả các tệp tải lên và hình thu nhỏ của chúng trong đối tượng Queue được duy trì trong phiên.

Quay lại chế độ xem: sau khi biểu mẫu được tạo bằng hình thu nhỏ được tạo lên, biểu mẫu đăng lại ProductController nơi tệp được chọn được xác định (hiện tại tôi lưu trữ tên tệp trong trường Ẩn, Tôi nhận ra là một lỗ hổng khủng khiếp), và sau đó sao chép ra khỏi thư mục tạm thời đến một vị trí cố định. Lý tưởng nhất, tôi muốn chỉ đơn giản là truy cập vào hàng đợi tôi đã lưu trữ trong phiên để các hình thức không cần phải chứa vị trí hình ảnh như nó hiện nay. Đây là cách tôi đã hình dung ra giải pháp của mình, nhưng tôi sẽ háo hức lắng nghe bất kỳ bình luận hay phê bình nào.

Trả lời

3

Một vài giải pháp được đề cập đến. Bạn có thể sử dụng lớp "SessionState" để ánh xạ vào yêu cầu và nhận/đặt thông tin như vậy (tôi đang làm điều này từ bộ nhớ để không thể biên dịch và có nghĩa là truyền đạt điểm):

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

Và sau đó từ bộ điều khiển, làm điều gì đó như:

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

Ngoài ra, bạn có thể tạo ra một phương pháp mở rộng điều khiển:

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

sau đó từ bộ điều khiển:

Điều này chắc chắn là KHÔ. Điều đó nói rằng, tôi không đặc biệt thích một trong các giải pháp này vì tôi thích lưu trữ càng ít dữ liệu, nếu có, trong phiên. Nhưng nếu bạn có ý định giữ tất cả thông tin này mà không phải tải/phân biệt nó với một số nguồn khác, thì đây là cách nhanh nhất (bẩn nhất) mà tôi có thể nghĩ đến.Tôi khá chắc chắn có một giải pháp thanh lịch hơn nhiều, nhưng tôi không có tất cả các thông tin về những gì nó là bạn đang cố gắng để làm và tên miền vấn đề là gì.

Hãy nhớ rằng khi lưu trữ thông tin trong phiên, bạn sẽ phải mất nước/bù nước các đối tượng thông qua serialization và bạn có thể không nhận được hiệu suất bạn nghĩ rằng bạn đang làm nó theo cách này.

Hy vọng điều này sẽ hữu ích.

CHỈNH SỬA: Để phản hồi thông tin bổ sung Không chắc chắn nơi bạn đang tìm cách triển khai điều này, nhưng xử lý hình ảnh "thời gian thực" là một cách chắc chắn sẽ bị tấn công DoS. Đề xuất của tôi cho bạn như sau - giả định rằng điều này là công khai và mọi người có thể tải lên hình ảnh:

1) Cho phép người dùng tải lên hình ảnh. Hình ảnh này đi vào hàng đợi xử lý để xử lý nền bởi ứng dụng hoặc một số dịch vụ. Ngoài ra, tên của hình ảnh đi vào hàng đợi xử lý cá nhân của người dùng - có thể là một bảng trong cơ sở dữ liệu. Bạn có thể tìm thấy thông tin về xử lý nền trong ứng dụng web @Schedule a job in hosted web server

2) Xử lý những hình ảnh này và trong khi xử lý, hiển thị "đồ họa xử lý". Bạn có thể có yêu cầu ajax trên trang sản phẩm để kiểm tra các hình ảnh đang được xử lý và truy xuất lại để tải lại chúng sau mỗi giây X.

3) Trong khi hình ảnh đang được "xử lý", người dùng có thể chọn không tham gia xử lý giả định rằng họ là người đã tải hình ảnh lên. Điều này có sẵn hoặc trên (các) trang sản phẩm hiển thị hình ảnh hoặc trên chế độ xem "xếp hàng người dùng" riêng biệt cho phép họ loại bỏ hình ảnh khỏi việc xem xét.

Vì vậy, bạn kết thúc với một số đối tượng miền khác và các đối tượng đó được quản lý bởi hàng đợi. Tôi là người ủng hộ mạnh mẽ quy ước về cấu hình nên đích cuối cùng của (các) hình ảnh sản phẩm phải được xác định trước. Một cái gì đó như:

hình ảnh/sản phẩm/{id} .jpg hoặc, nếu một bộ sưu tập, hình ảnh/sản phẩm/{id}/{chuỗi} .jpg.

Sau đó, bạn không cần phải biết đích đến trong biểu mẫu. Nó giống nhau cho tất cả các hình ảnh.

Hàng đợi sau đó cần biết vị trí hình ảnh tạm thời được tải lên và ID sản phẩm là gì. Nhân viên xếp hàng xuất hiện các mục từ hàng đợi, xử lý chúng và lưu trữ chúng cho phù hợp.

Tôi biết điều này nghe có vẻ hơi "có cấu trúc" hơn những gì bạn dự định ban đầu, nhưng tôi nghĩ nó sạch hơn một chút.

+0

Cảm ơn bạn đầu vào này. Tôi đã thêm một số thông tin thêm vào câu hỏi ban đầu của tôi nếu đó là bất kỳ sử dụng thêm. –

+0

Việc xử lý hình ảnh là thời gian thực, nhưng tồn tại bên trong một khu vực quản trị để trang web, do đó, việc sử dụng tổng thể của nó là khá tối thiểu. Tối đa, chỉ một vài hình ảnh có khả năng được xử lý mỗi giờ trên toàn bộ ứng dụng. Một cách tiếp cận khác mà tôi cũng xem xét đơn giản là có sự kiện Session_End của ứng dụng xóa toàn bộ thư mục tạm thời cho phiên hiện tại, nhưng tôi không chắc là lý tưởng đó là như thế nào. –

+0

Nếu người dùng của bạn đã tải lên rất nhiều hình ảnh đang xử lý, tôi không nghĩ rằng bạn có thể đảm bảo rằng nó sẽ được thực hiện khi phiên của họ hết hạn. Tôi sẽ xóa nó sau khi "xử lý" đã hoàn thành. Các luồng công nhân (s) nên được duy trì miễn là hàng đợi có các mục cần xử lý để an toàn để giả định điều đó. Miễn là hồ bơi ứng dụng của bạn không "ngủ", hệ thống của bạn sẽ tiếp tục xử lý ok. Khá chắc chắn nó được đề cập trong bài báo tôi đã liên kết. – andymeadows

1

Có hoàn toàn tương đương giữa UploadController và ProductController không?

Khi tệp được tải lên bởi tệp UploadController, dữ liệu về tải lên được lưu trữ trong Phiên. Sau khi điều này xảy ra, tôi cần truy cập dữ liệu Session đó trong ProductController.

Khi tôi đọc rằng UploadControl cần quyền truy cập đọc và ghi vào dữ liệu Tải lên, ProductController chỉ cần đọc.

Nếu đó là sự thật thì bạn có thể làm cho nó rõ ràng bằng cách sử dụng một wrapper immuatable xung quanh thông tin tải lên và có UploadController đặt đó vào phiên.

Chính phiên là bằng cách xác định một bảng thông báo được chia sẻ công khai, tách riêng các mối quan hệ rõ ràng với chi phí cho phép mọi người nhận và đặt. Bạn có thể cho phép ProductController biết về UploadController và do đó loại bỏ nhu cầu chuyển thông tin tải lên qua phiên. Bản năng của tôi là thông tin tải lên thú vị với công chúng, vì vậy việc sử dụng Phiên là hợp lý.

Tôi không thấy bất kỳ vi phạm DRY nào ở đây, chúng tôi đang cố gắng tách biệt trách nhiệm một cách rõ ràng.

+0

Tôi không chắc chắn nếu điều này đủ điều kiện như là một vấn đề DRY hoặc chỉ là một trong những giao tiếp thành phần được xác định kém. Phiên được thiết kế rõ ràng để thu hẹp khoảng cách chính xác mà tôi đang cố gắng lấp đầy, nó chỉ không cảm thấy đặc biệt trong trường hợp này. –

Các vấn đề liên quan