2013-06-07 28 views
14

Hello Razor MVC Gurus:Dao động MVC, nơi đặt các biến toàn cầu có thể truy cập trên trang chính, partiview và xem?

Câu hỏi mới.

Bối cảnh. Tôi có một IIdentity tùy chỉnh được thiết lập trong một HttpModule trước khi nó được để điều khiển & xem. Để sử dụng nó, tôi phải làm

MyIdentity myIdentity = (MyIdentity)((GenericPrincipal)context.User).Identity; 
    MyComplexUser user = myIdentity.User; 
    //user.name //user.location //user.username //etc 

Vấn đề là, tôi sử dụng các đối tượng ở những nơi khác nhau như

  • bố trí tổng thể
  • Một số phụ cấp bố trí lồng nhau
  • Một số partialviews
  • Một số lượt xem

Nó thực sự depe nds về những thuộc tính của đối tượng "MyComplexUser" mà các khung nhìn cần.

Hiện tại, trong chế độ xem, tôi phải thực hiện thao tác truyền thực sự phức tạp này để truy cập thuộc tính. Ví dụ: nếu tôi muốn "Tên" của người dùng, tôi cần phải làm

@ (((MyComplexUser) (((MyIdentity) (GenericPrincipal) context.User) .Identity) .User)).)

tôi cho rằng tôi có thể đặt nó trong bộ điều khiển và sau đó cư ViewBag với một tài sản ViewBag.MyUser, nhưng sau đó

  1. tôi không muốn sử dụng ViewBag. Tôi thích các đối tượng được nhập mạnh mẽ
  2. Nếu tôi sử dụng đối tượng được nhập mạnh ("MyUser") cho chế độ xem thì tôi phải phổ biến tất cả các mô hình đó bằng thuộc tính "MyUser". Cảm thấy một chút bẩn? Vì tôi muốn giữ cho các mô hình của mình luôn sạch sẽ và cụ thể cho các chế độ xem mà họ có liên quan. Bên cạnh đó, nó được lặp đi lặp lại không cần thiết.
  3. Ở những nơi như master_layout.cshtml hoặc partviews, làm cách nào để bạn truy cập "MyUser" nếu tôi đặt chúng trong bộ điều khiển?
  4. Sử dụng RenderAction và xây dựng một phần xem trước cho từng thuộc tính Người dùng là quá mức cần thiết?

Cảm ơn. Một lần nữa, tôi là một newbie tại MVC 4, bất cứ đề nghị nào cũng đánh giá cao nó.

+1

Tôi có một kịch bản tương tự. Tôi sẽ đăng nó như một bình luận, nếu bạn thích tôi có thể thêm vào như một câu trả lời: tất cả các bộ điều khiển của tôi kế thừa từ một 'BaseController', mà tôi đã viết. Trong lớp cơ sở này, tôi đã kết nối các sự kiện của vòng đời, chẳng hạn như 'ExecuteCore'. Tôi cũng sử dụng bộ lọc cho những thứ như thế này. Ở phía bên xem, tất cả các kiểu xem của tôi kế thừa từ 'BaseVM', nơi tôi đặt các thuộc tính chung, chẳng hạn như các thông báo cho người dùng, tên người dùng và vân vân. –

+0

@AndreCalil, bạn có thể giải thích thêm một chút không? Vì vậy, bạn đang cư trú một mô hình cơ sở từ bộ điều khiển cơ sở, là nó? Tôi không nhận được phần mà bạn sử dụng bộ lọc, bạn có thể đưa ra ví dụ không? Ngoài ra, nếu bạn điền các thuộc tính phổ biến trong mô hình cơ sở, bạn sử dụng nó như thế nào trong trang bố cục chính? do \\ @ Model BaseVM và sau đó \\ @ Model.UserName? Cảm ơn – Liming

+1

Bạn đã đến. Và tôi không nghĩ rằng đây là một câu hỏi mới ở tất cả các số –

Trả lời

21

Tôi sẽ giải thích một giải pháp tương tự hoạt động khá tốt đối với tôi. Với những thay đổi nhỏ, tôi tin rằng rằng nó sẽ làm việc cho bạn (và những người khác, hy vọng) là tốt.

Về cơ bản, chúng tôi sẽ sử dụng thừa kế.

Controller

Hãy tạo một bộ điều khiển cơ sở tùy chỉnh, chẳng hạn như

public class BaseController : Controller 

và chúng ta hãy thay đổi các bộ điều khiển của chúng tôi để kế thừa từ nó, như

public class HomeController : BaseController 

Models (ViewModels, tôi nói)

Bạn có thể có nhiều lớp học bên trong Mô hình của bạn der, phải không? Chúng hoạt động như DTO từ bộ điều khiển đến các chế độ xem, phải không? Nếu bạn trả lời cho cả hai, sau đó tiếp tục đọc.

Hãy tạo ra một lớp mô hình cơ sở, chẳng hạn như public class BaseVM, và chúng ta hãy thay đổi mô hình của chúng tôi để kế thừa từ nó, như public class HomeIndex : BaseVM

Chú ý: file layout của bạn (_Layout hoặc bất cứ điều gì) phải được đánh máy mạnh mẽ để BaseVM hoặc một đứa trẻ của nó.

Móc

Bây giờ mọi thứ đều được nhập đẹp, hãy sử dụng đường ống yêu cầu có lợi cho chúng tôi. Tại BaseController, bạn sẽ thêm một phương pháp mà trông như thế này:

protected override void OnActionExecuted(ActionExecutedContext filterContext) 
{ 
    if (filterContext.Result is ViewResultBase)//Gets ViewResult and PartialViewResult 
    { 
     object viewModel = ((ViewResultBase)filterContext.Result).Model; 

     if (viewModel != null && viewModel is BaseVM) 
     { 
      BaseVM baseVM = viewModel as BaseVM; 

      baseVM.MyIdentity = (MyIdentity)((GenericPrincipal)context.User).Identity; 
      //and so on... 
     } 
    } 

    base.OnActionExecuted(filterContext);//this is important! 
} 

OnActionExecuted được gọi sau thực hiện các hành động nhưng trước quan điểm vẽ. Đó chính là điều chúng tôi muốn.

Tôi hy vọng bạn đã có nó. =)

+0

OK! Cảm ơn Andre. BaseController + BaseModel có ý nghĩa :) Cảm ơn rất nhiều lần nữa! – Liming

+0

@Liming Rất vui khi được giúp =) –

+0

Giải pháp tốt - cuối cùng là cách dễ dàng để truyền đối tượng tới tất cả các chế độ xem mà không cần phải sử dụng ViewBag. – 79IT

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