Я також хотів розмістити файли js, пов’язані з видом, в ту саму папку, що і представлення.
Мені не вдалося змусити інші рішення в цьому потоці працювати, не те, що вони зламані, але я занадто новачок у MVC, щоб змусити їх працювати.
Використовуючи наведену тут інформацію та кілька інших стеків, я придумав рішення, яке:
- Дозволяє розміщувати файл javascript у тому самому каталозі, що і подання, з яким він пов'язаний.
- URL-адреси сценарію не видають базової фізичної структури сайту
- URL-адреси сценарію не повинні закінчуватися косою рискою (/)
- Не заважає статичним ресурсам, наприклад: /Scripts/someFile.js все ще працює
- Не вимагає активації runAllManagedModulesForAllRequests.
Примітка: Я також використовую маршрутизацію атрибутів HTTP. Цілком можливо, що маршрут, який використовується в моєму розумінні, може бути модифікований для роботи, не дозволяючи цього.
Враховуючи такий приклад структури каталогу / файлу:
Controllers
-- Example
-- ExampleController.vb
Views
-- Example
-- Test.vbhtml
-- Test.js
За допомогою кроків конфігурації, наведених нижче, у поєднанні з наведеною вище /Example/Test
зразковою структурою, до URL-адреси тестового подання можна буде отримати доступ за допомогою: а файл javascript матиме посилання через:/Example/Scripts/test.js
Крок 1 - Увімкнути маршрутизацію атрибутів:
Відредагуйте файл /App_start/RouteConfig.vb і додайте routes.MapMvcAttributeRoutes()
трохи вище існуючих маршрутів.
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Web
Imports System.Web.Mvc
Imports System.Web.Routing
Public Module RouteConfig
Public Sub RegisterRoutes(ByVal routes As RouteCollection)
routes.IgnoreRoute("{resource}.axd/{*pathInfo}")
' Enable HTTP atribute routing
routes.MapMvcAttributeRoutes()
routes.MapRoute(
name:="Default",
url:="{controller}/{action}/{id}",
defaults:=New With {.controller = "Home", .action = "Index", .id = UrlParameter.Optional}
)
End Sub
End Module
Крок 2 - Налаштуйте свій сайт на обробку та обробку /{controller}/Scripts/*.js як шляху MVC, а не статичного ресурсу
Відредагуйте файл /Web.config, додавши до файлу system.webServer -> обробників файлу наступне:
<add name="ApiURIs-ISAPI-Integrated-4.0" path="*/scripts/*.js" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
Ось знову з контекстом:
<system.webServer>
<modules>
<remove name="TelemetryCorrelationHttpModule"/>
<add name="TelemetryCorrelationHttpModule" type="Microsoft.AspNet.TelemetryCorrelation.TelemetryCorrelationHttpModule, Microsoft.AspNet.TelemetryCorrelation" preCondition="managedHandler"/>
<remove name="ApplicationInsightsWebTracking"/>
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" preCondition="managedHandler"/>
</modules>
<validation validateIntegratedModeConfiguration="false"/>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0"/>
<remove name="OPTIONSVerbHandler"/>
<remove name="TRACEVerbHandler"/>
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0"/>
<add name="ApiURIs-ISAPI-Integrated-4.0" path="*/scripts/*.js" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
Крок 3 - Додайте наступні результати дії сценаріїв до вашого файлу контролера
- Обов’язково відредагуйте шлях маршруту, щоб він відповідав імені {controller} для контролера, для цього прикладу це: <Route (" Example / Scripts / {filename}")>
Вам потрібно буде скопіювати це у кожен з ваших файлів контролера. Якщо ви хочете, можливо, є спосіб зробити це як єдину, одноразову конфігурацію маршруту.
' /Example/Scripts/*.js
<Route("Example/Scripts/{filename}")>
Function Scripts(filename As String) As ActionResult
' ControllerName could be hardcoded but doing it this way allows for copy/pasting this code block into other controllers without having to edit
Dim ControllerName As String = System.Web.HttpContext.Current.Request.RequestContext.RouteData.Values("controller").ToString()
' the real file path
Dim filePath As String = Server.MapPath("~/Views/" & ControllerName & "/" & filename)
' send the file contents back
Return Content(System.IO.File.ReadAllText(filePath), "text/javascript")
End Function
Для контексту це мій файл ExampleController.vb:
Imports System.Web.Mvc
Namespace myAppName
Public Class ExampleController
Inherits Controller
' /Example/Test
Function Test() As ActionResult
Return View()
End Function
' /Example/Scripts/*.js
<Route("Example/Scripts/{filename}")>
Function Scripts(filename As String) As ActionResult
' ControllerName could be hardcoded but doing it this way allows for copy/pasting this code block into other controllers without having to edit
Dim ControllerName As String = System.Web.HttpContext.Current.Request.RequestContext.RouteData.Values("controller").ToString()
' the real file path
Dim filePath As String = Server.MapPath("~/Views/" & ControllerName & "/" & filename)
' send the file contents back
Return Content(System.IO.File.ReadAllText(filePath), "text/javascript")
End Function
End Class
End Namespace
Заключні примітки
У файлах javascript test.vbhtml view / test.js немає нічого особливого, і вони тут не відображаються.
Я зберігаю свій CSS у файлі представлення, але ви можете легко додати це рішення, щоб можна було посилатися на ваші файли CSS подібним чином.