Também queria colocar os arquivos js relacionados a uma visualização na mesma pasta da visualização.
Não fui capaz de fazer as outras soluções neste segmento funcionarem, não que elas estejam quebradas, mas sou muito novo no MVC para fazê-las funcionar.
Usando as informações fornecidas aqui e várias outras pilhas, encontrei uma solução que:
- Permite que o arquivo javascript seja colocado no mesmo diretório da visualização à qual está associado.
- Os URLs de script não revelam a estrutura física subjacente do site
- O URL do script não precisa terminar com uma barra final (/)
- Não interfere com recursos estáticos, por exemplo: /Scripts/someFile.js ainda funciona
- Não requer runAllManagedModulesForAllRequests para ser ativado.
Observação: também estou usando o roteamento de atributo HTTP. É possível que a rota usada na minha alma possa ser modificada para funcionar sem habilitar isso.
Dado o seguinte exemplo de estrutura de diretório / arquivo:
Controllers
-- Example
-- ExampleController.vb
Views
-- Example
-- Test.vbhtml
-- Test.js
Usando as etapas de configuração fornecidas abaixo, combinadas com a estrutura do exemplo acima, o URL de visualização de teste seria acessado por meio de: /Example/Test
e o arquivo javascript seria referenciado por meio de:/Example/Scripts/test.js
Etapa 1 - Habilitar Roteamento de Atributo:
Edite seu arquivo /App_start/RouteConfig.vb e adicione routes.MapMvcAttributeRoutes()
logo acima das rotas existentes.MapRoute:
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
Etapa 2 - configure seu site para tratar e processar /{controller}/Scripts/*.js como um caminho MVC e não um recurso estático
Edite seu arquivo /Web.config, adicionando o seguinte à seção system.webServer -> handlers do arquivo:
<add name="ApiURIs-ISAPI-Integrated-4.0" path="*/scripts/*.js" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
Aqui está novamente com contexto:
<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>
Etapa 3 - Adicione o seguinte resultado de ação de scripts ao arquivo do controlador
- Certifique-se de editar o caminho da rota para corresponder ao nome do {controlador} para o controlador, para este exemplo é: <Route (" Exemplo / Scripts / {nome do arquivo}")>
Você precisará copiar isso para cada um dos arquivos do controlador. Se você quiser, provavelmente há uma maneira de fazer isso como uma configuração de rota única e única.
' /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
Para contexto, este é meu arquivo 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
Notas finais
Não há nada de especial sobre os arquivos javascript test.vbhtml view / test.js e não são mostrados aqui.
Eu mantenho meu CSS no arquivo de visualização, mas você pode facilmente adicionar a esta solução para que possa referenciar seus arquivos CSS de maneira semelhante.