9

Tôi đã ghi đè cho bộ điều khiển kiểm tra xem dữ liệu phiên nhất định có tồn tại không. Dữ liệu này được yêu cầu để kho lưu trữ hoạt động bình thường, vì vậy nếu nó không tồn tại thì sau khi kiểm tra người dùng sẽ được đăng xuất.Chuyển hướng từ Bộ điều khiển Khởi tạo không hoạt động

protected override void Initialize(System.Web.Routing.RequestContext requestContext) 
{ 
    base.Initialize(requestContext); 
    if (Session["CompanyID"] != null) 
    { 
     repo.CompanyID = (long)Session["CompanyID"]; 
    } 
    else 
    { 
     RedirectToAction("LogOff", "Account"); 
    } 
} 

Mã của tôi trông như thế này, nhưng ngay cả khi RedirectToAction được gọi là bộ điều khiển vẫn mở hành động mặc định và người dùng chưa đăng xuất. Bạn có thể giới thiệu cách xử lý vấn đề này không?

Tôi đang sử dụng dữ liệu phiên này theo cách như vậy vì đây là nơi đầu tiên tôi có thể truy cập được và tôi có thể kiểm tra xem dữ liệu cụ thể này có tồn tại không. Nó được viết khi người dùng đăng nhập.

Dữ liệu này là một phần của Người dùng trong cơ sở dữ liệu. Tôi đã tạo thành viên tùy chỉnh và nhà cung cấp vai trò. Có cách nào để thêm dữ liệu này để "Người dùng" của loại MembershipUser bằng cách nào đó để nó có thể được truy cập trong constructor như tên người dùng?

Trả lời

12

Thay vào đó, hãy cân nhắc sử dụng tùy chỉnh ActionFilter.

public class HasCompanyIdAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     if (filterContext.HttpContext.Session["CompanyID"] == null) 
     { 
      filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new {action = "LogOff", controller = "Account"})); 
     } 
    } 
} 

Nó sau đó có thể được áp dụng như vậy:

[HasCompanyId] 
public class MyController : Controller 
{ 
    public ActionResult SomeAction() 
    { 
     return View(); 
    } 
} 

này sẽ áp dụng các thuộc tính cho tất cả các yêu cầu mà MyController (hoặc đó là lớp con) xử lý.

+0

Tôi hiểu nguyên tắc, nhưng có vẻ hơi không thực tế. Tôi không thể làm cho nó một bộ lọc toàn cầu vì có các khu vực công cộng của ứng dụng, và sau đó tôi phải áp dụng nó cho mọi hành động bên trong khu vực yêu cầu nó? Có cách nào khác để phá vỡ tải của bộ điều khiển sau khi khởi tạo và gửi nó đến hành động khác của bộ điều khiển khác? – Zaak

+0

Bạn có thể áp dụng thuộc tính cho bộ điều khiển, và nó sẽ được áp dụng cho mọi hành động trong bộ điều khiển đó, hoặc một lớp cơ sở điều khiển và sau đó hành động sẽ được áp dụng cho mọi hành động của lớp dẫn xuất! –

+0

Hmm, cách này vẫn không giải quyết được sự thật tôi phải đặt nó một lần. Dường như việc thực hiện mọi thứ thông qua FilterAttribute theo cách này sẽ thiết lập nó mỗi khi một hành động thực hiện thay vì chỉ khi Controller được khởi tạo? – Zaak

2

Chỉ cần triển khai giải pháp của bạn bằng cách ghi đè OnActionExcuting trong lớp cơ sở thay thế. Sau đó, bạn có thể làm mọi thứ bạn có thể thực hiện trong Bộ lọc hành động. Giống như vậy:

public void OnActionExecuting(ActionExecutingContext filterContext){ 
    if (filterContext.HttpContext.Session["CompanyID"] != null) 
    repo.CompanyID = (long)filterContext.HttpContext.Session["CompanyID"]; 
    else 
    filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new {action = "LogOff", controller = "Account"})); 
} 

Một số mã bị bỏ qua cho ngắn gọn.

Tôi đã thử cả hai cách tiếp cận và tìm thấy việc triển khai nó thông qua một bộ lọc hành động phức tạp hơn do các yêu cầu về Dependency Injection mà tôi có. Bạn có thể làm điều đó một trong hai cách nhưng cảm thấy cách tiếp cận lớp cơ sở là một chút rõ ràng hơn. Tôi cũng muốn thiết lập một số thuộc tính trên lớp cơ sở để tạo ra một vài đối tượng tiêu chuẩn có sẵn cho các phương thức điều khiển để lưu các mã DEV lặp đi lặp lại được thêm vào các hành động. Cách tiếp cận lớp cơ sở thực hiện điều này dễ dàng. Một báo trước tôi sẽ thêm là tôi không đề xuất đây là một cách tiếp cận tốt để xác thực/bảo mật, tôi xem xét điều này hoàn toàn từ quan điểm muốn thực hiện một số hoạt động/xác thực trước khi thực thi hành động và cũng thiết lập một số dữ liệu được điền trước trên cá thể bộ điều khiển để tuân theo nguyên tắc DRY.

Hy vọng điều đó sẽ hữu ích.

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