2013-05-02 38 views
5

Tôi đang viết một phần mở rộng HtmlHelper và tôi cần tìm kiếm sự tồn tại của mẫu theo tên. Mẫu được đề cập có thể là mẫu hiển thị hoặc trình chỉnh sửa tùy thuộc vào ngữ cảnh. Suy nghĩ ban đầu của tôi là sử dụng phương pháp ViewEngines.Engines.FindPartialView. Tuy nhiên, có vẻ như phương pháp này không tìm kiếm các thư mục ~/Views/Shared/DisplayTemplates~/Views/Shared/EditorTemplates.
Tôi cho rằng đây là lý do chính đáng. Xét cho cùng, làm thế nào để ViewEngine biết liệu có trả về mẫu hiển thị hoặc trình soạn thảo mà không có thêm một số thông tin về ngữ cảnh không?Tìm chế độ xem mẫu MVC theo tên

Vì vậy, điều đó dẫn đến câu hỏi: làm thế nào tôi có thể tìm kiếm một cụ EditorTemplate/DisplayTemplate tôi đã xem xét bổ sung thêm một công cụ xem tùy chỉnh để bộ sưu tập ViewEngines để bao gồm các địa điểm này. Tuy nhiên, tôi lo ngại rằng điều này có thể là vấn đề.

Mối quan tâm chính của tôi là hiển thị DisplayTemplate/EditorTemplate Chế độ xem có thể được phục vụ cho mục đích không mong muốn. Có ai khác nhìn thấy điều này như là một vấn đề?
Có một ý tưởng hay hơn là chỉ cần tạo một cá thể DisplayTemplateViewEngine/EditorTemplateViewEngine cụ thể khi cần thiết và giữ bộ sưu tập ViewEngines rõ ràng về chức năng cụ thể này?
Tôi còn thiếu cái gì khác không?

Trả lời

4

Tôi hoàn toàn thích rằng khung MVC là mở nguồn! Tôi đã có thể xác định, từ lớp TemplateHelpers (bên trong MVC Runtime) mà DataBoundControlMode được xem xét khi render một khuôn mẫu. Câu trả lời rất đơn giản! Tất cả tôi phải làm là tiền tố tên mẫu với các giám đốc mẫu thích hợp. Vì vậy, để tìm một mẫu màn hình:

var metadata = ModelMetadata.FromLambdaExpression(expression, HtmlHelper.ViewData); 
ViewEngines.Engines.FindPartialView(
    _controllerContext, 
    string.Format("DisplayTemplates/{0}", metadata.TemplateHint)) 

Không động cơ xem bổ sung hoặc yêu cầu định tuyến! Trong trường hợp bạn quan tâm đến ứng dụng, trình trợ giúp của tôi là tự động tạo các thành phần giao diện người dùng cho một mô hình cụ thể. Tôi muốn kích hoạt sự tồn tại của một mẫu tùy chỉnh để bỏ qua hiển thị tự động.

+0

Đây là câu trả lời. Tuy nhiên tôi không thể đánh dấu nó như vậy trong một vài ngày. Xin lỗi nếu bạn bị thu hút bởi bài đăng này vì trạng thái 'chưa được trả lời' rõ ràng. –

+0

Siêu dữ liệu là gì.TemplateHint hoặc từ đâu đến? – xr280xr

+1

@ xr280xr: Đã cập nhật để bao gồm định nghĩa siêu dữ liệu. Hy vọng rằng phục vụ bạn! –

0

A WebFormViewEngine có một số thuộc tính xác định (các mẫu cho) vị trí để tìm kiếm chế độ xem.

Bạn có thể theo quy ước của công cụ xem mà bạn sử dụng hoặc tạo công cụ chế độ xem tùy chỉnh (dành cho examlpe mở rộng Razor) với đường dẫn chế độ xem tùy chỉnh.

Sau đó được giải thích here:

public class CustomViewEngine : RazorViewEngine 
{ 
    public CustomViewEngine() 
    { 
     var viewLocations = new[] { 
      "~/Views/{1}/{0}.cshtml", 
      "~/Views/Shared/{0}.cshtml", 
      "~/Views/Shared/DisplayTemplates/{0}.cshtml", 
      "~/Views/Shared/DisplayTemplates/{1}/{0}.cshtml", 
      // etc 
     }; 

     this.PartialViewLocationFormats = viewLocations; 
     this.ViewLocationFormats = viewLocations; 
    } 
} 

Vì vậy, tôi đoán trong helper của bạn, bạn nên tìm kiếm các công cụ xem hiện tại và nhìn lên xem đường dẫn vị trí của nó và tìm kiếm chúng theo thứ tự. Không phải là trình trợ giúp Html có phương pháp hoặc thuộc tính để có chế độ xem bạn hiện đang chạy không?

+0

Cảm ơn bạn đã trả lời. Tôi không thực sự phá vỡ quy ước; cấu trúc của tôi là với các định nghĩa kiến ​​trúc MVC dự kiến.Vấn đề là phương thức FindPartialView của ViewEnginesCollection không tìm kiếm các vị trí đó bởi vì nó sẽ không biết nếu bạn muốn hiển thị hoặc phiên bản trình soạn thảo. Tôi đã tìm thấy một giải pháp, tuy nhiên. Xem câu trả lời của tôi để tham khảo. Cảm ơn một lần nữa. –

+0

1) Mã trong ví dụ của bạn có phải là hành vi Dao cạo mặc định không? 2) '{0}' và '{1}' là gì? – Shimmy

+0

@Shimmy [đây là mặc định] (https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/System.Web.Mvc/RazorViewEngine.cs). Các giá trị thay thế là '{0}' = tên xem, '{1}' = tên bộ điều khiển và '{2}' = tên khu vực (xem ['ViewLocation' và' AreaAwareViewLocation' ở dưới cùng của tệp này] (https: //github.com/ASP-NET-MVC/aspnetwebstack/blob/4e40cdef9c8a8226685f95ef03b746bc8322aa92/src/System.Web.Mvc/VirtualPathProviderViewEngine.cs)). – CodeCaster

0

Tại sao bạn chỉ cần lập bản đồ các đường dẫn tương đối

string path = Server.MapPath("~/View/"); 

Và sau đó kiểm tra nếu các lối ra tập tin dựa trên lối ra của .cshtml trong đó thư mục cụ thể

string fileName = "MyView.cshtml"; 
if (File.Exists(path + fileName)) 
    //do somethings 
else 
    //do another things 
+0

Một lợi ích của việc sử dụng ViewEngine là nó có thể được chế nhạo làm cho nó có thể kiểm chứng được. Giải pháp này thực sự khó khăn để kiểm tra đơn vị. Vui mừng cho đầu vào của bạn, mặc dù! –

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