2011-01-13 26 views
9

Vì vậy, tôi có một con đường như thế này trong ứng dụng MVC 3 của tôi chạy dưới IIS 7:MVC định tuyến khi một tập tin thực sự tồn tại ở vị trí quy định

routes.MapRoute(
       "VirtualTourConfig", 
       "virtualtour/config.xml", 
       new { controller = "VirtualTour", action = "Config" } 
       ); 

Bí quyết là một tập tin thực sự tồn tại ở/virtualtour/config.xml. Có vẻ như yêu cầu này chỉ trả về tệp xml tại vị trí đó thay vì nhấn tuyến đường, xử lý XML, thực hiện một số thay đổi và trả về một XmlResult tùy chỉnh.

Bất kỳ đề xuất nào về cách tôi có thể yêu cầu ứng dụng của tôi truy cập tuyến đường chứ không phải tệp thực sự trong trường hợp tệp tồn tại trên đĩa?

EDIT: Dường như tôi có thể sử dụng routes.RouteExistingFiles = true; trong phương pháp RegisterRoutes của Global.asax để yêu cầu ứng dụng bỏ qua các tệp trên đĩa. Tuy nhiên, điều này đặt cờ toàn cầu và phá vỡ nhiều yêu cầu khác trong ứng dụng. Ví dụ, tôi vẫn muốn các cuộc gọi đến /assets/css/site.css để trả về tệp CSS mà không cần phải thiết lập cụ thể các tuyến cho mỗi tài sản tĩnh. Vì vậy, bây giờ câu hỏi trở thành, là có một cách để làm điều này trên cơ sở mỗi tuyến đường?

+3

Tôi không nghĩ rằng có một cách dễ dàng để đạt được điều này. Tại sao bạn không chỉ cần di chuyển tệp tĩnh vào thư mục '~/App_Data'? –

Trả lời

6

Cho đến nay, câu trả lời hay nhất mà tôi thấy là áp dụng toàn cầu routes.RouteExistingFiles=true và sau đó chọn lọc bỏ qua các tuyến đường tôi muốn chuyển đến các tệp hiện có như .js, .css, v.v. này:

public static void RegisterRoutes(RouteCollection routes) 
     { 
      routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 
      routes.IgnoreRoute("*.js|css|swf"); 
      routes.RouteExistingFiles = true; 

      routes.MapRoute(
       "VirtualTourConfig", 
       "virtualtour/config.xml", 
       new { controller = "VirtualTour", action = "Config" } 
       ); 
} 

Nếu có giải pháp nào tốt hơn, tôi muốn xem. Tôi rất muốn áp dụng có chọn lọc một lá cờ "RouteExistingFIles" để các tuyến đường cá nhân nhưng tôi không biết nếu có một cách để làm điều đó.

0

Không có giải pháp nào ở đây, chỉ là một ý tưởng.

Bạn có thể thử triển khai giải pháp dựa trên VirtualPathProvider của riêng mình để cung cấp ánh xạ đường dẫn web của riêng bạn để tạo đường dẫn hệ thống và sử dụng nhà cung cấp mặc định cho tất cả đường dẫn bạn không muốn chăm sóc.

0

Một giải pháp rất đơn giản, chắc chắn nếu bạn xem xét câu trả lời của Scott, ví dụ: routes.IgnoreRoute("templates/*.html");, routes.IgnoreRoute("scripts/*.js");routes.IgnoreRoute("styles/*.css");.

Điều này mang lại cho bạn cả sự đơn giản của việc chỉ cung cấp đường dẫn đến RoutesCollection và tránh việc phải bắt đầu ví dụ. một VirtualPathProvider.

0

Bạn có thể thử UrlRewiting ví dụ:

<configuration> 
    <system.webServer> 
    <rewrite> 
     <rules> 
     <rule name="VirtualTourConfig"> 
      <match url="^virtualtour/config.xml" /> 
      <action type="Rewrite" url="virtualtour/config" /> 
     </rule> 
     </rules> 
    </rewrite> 

NB Tôi đang sử dụng này cho một use-case khác nhau (tức là phục vụ một ứng dụng góc từ asp.net MVC) - Tôi đã không kiểm tra liệu MVC định tuyến xảy ra sau khi viết lại url.

Trong trường hợp của tôi, tôi có một lộ trình MVC bình thường (ví dụ: /Dashboard/ =>DashboardController.Index()) nhưng cần tất cả đường dẫn tương đối trong Views/Dashboard/Index.cshtml để phục vụ các tập tin tĩnh mà không bị nhầm lẫn bởi MVC định tuyến ví dụ: /Dashboard/app/app.module.js phải phục vụ cho một tập tin tĩnh. Tôi sử dụng UrlRewriting để bản đồ /Dashboard/(.+) đến /ng/Dashboard/{R:1} như sau:

<configuration> 
    <system.webServer> 
    <rewrite> 
     <rules> 
     <rule name="Dashboard"> 
      <match url="^dashboard/(.+)" /> 
      <action type="Rewrite" url="ng/dashboard/{R:1}" /> 
     </rule> 
     </rules> 
    </rewrite> 
Các vấn đề liên quan