También quería colocar archivos js relacionados con una vista en la misma carpeta que la vista.
No pude hacer que las otras soluciones en este hilo funcionen, no es que estén rotas, pero soy demasiado nuevo en MVC para que funcionen.
Usando la información proporcionada aquí y varias otras pilas, se me ocurrió una solución que:
- Permite que el archivo javascript se coloque en el mismo directorio que la vista a la que está asociado.
- Las URL del script no revelan la estructura física subyacente del sitio
- Las URL del script no tienen que terminar con una barra inclinada (/)
- No interfiere con los recursos estáticos, por ejemplo: /Scripts/someFile.js todavía funciona
- No requiere que se habilite runAllManagedModulesForAllRequests.
Nota: también estoy usando el enrutamiento de atributos HTTP. Es posible que la ruta que se usa en mi alma pueda modificarse para que funcione sin habilitar esto.
Dado el siguiente ejemplo de estructura de directorio / archivo:
Controllers
-- Example
-- ExampleController.vb
Views
-- Example
-- Test.vbhtml
-- Test.js
Usando los pasos de configuración que se indican a continuación, combinados con la estructura de ejemplo anterior, se accedería a la URL de la vista de prueba a través de: /Example/Testy se haría referencia al archivo javascript a través de:/Example/Scripts/test.js
Paso 1: habilitar el enrutamiento de atributos:
Edite su archivo /App_start/RouteConfig.vb y agréguelo routes.MapMvcAttributeRoutes()justo encima de las rutas existentes.
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
Paso 2: configure su sitio para tratar y procesar /{controller}/Scripts/*.js como una ruta MVC y no como un recurso estático
Edite su archivo /Web.config, agregando lo siguiente a la sección system.webServer -> handlers del archivo:
<add name="ApiURIs-ISAPI-Integrated-4.0" path="*/scripts/*.js" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
Aquí está de nuevo con 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>
Paso 3: agregue el siguiente resultado de la acción de scripts a su archivo de controlador
- Asegúrese de editar la ruta de la ruta para que coincida con el nombre de {controlador} para el controlador, para este ejemplo es: <Ruta (" Ejemplo / Scripts / {nombre de archivo}")>
Deberá copiar esto en cada uno de sus archivos de Controller. Si lo desea, probablemente haya una manera de hacer esto como una configuración de ruta única y única de alguna manera.
' /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 el contexto, este es mi archivo 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 finales
No hay nada especial sobre los archivos javascript test.vbhtml view / test.js y no se muestran aquí.
Guardo mi CSS en el archivo de vista, pero podría agregarlo fácilmente a esta solución para que pueda hacer referencia a sus archivos CSS de una manera similar.