¿Dónde colocar los archivos javascript específicos de la vista en una aplicación ASP.NET MVC?

¿Cuál es el mejor lugar (qué carpeta, etc.) para colocar los archivos javascript específicos de la vista en una aplicación ASP.NET MVC?

Para mantener mi proyecto organizado, me encantaría poder ponerlos junto a los archivos .aspx de la vista, pero no he encontrado una buena manera de hacer referencia a ellos al hacerlo sin exponer las ~ / Vistas / Estructura de acción / carpeta. ¿Es realmente malo dejar que se filtren los detalles de esa estructura de carpetas?

La alternativa es ponerlos en las carpetas ~ / Scripts o ~ / Content, pero es una irritación menor porque ahora tengo que preocuparme por los conflictos entre los nombres de los archivos. Es una irritación que puedo superar, sin embargo, si es “lo correcto”.

Una vieja pregunta, pero quería poner mi respuesta en caso de que alguien más la busque.

Yo también quería ver mis archivos js / css específicos en la carpeta de vistas, y así es como lo hice:

En la carpeta web.config en la raíz de / Views, necesita modificar dos secciones para permitir que el servidor web sirva los archivos:

                 

Luego, desde su archivo de vista puede hacer referencia a las URL como espera:

 @Url.Content("~/Views//somefile.css") 

Esto permitirá la entrega de archivos .js y .css, y prohibirá la entrega de cualquier otra cosa.

Una forma de lograr esto es suministrar tu propio ActionInvoker . Usando el código incluido a continuación, puede agregar al constructor de su controlador:

 ActionInvoker = new JavaScriptActionInvoker(); 

Ahora, cada vez que coloque un archivo .js junto a su vista:

enter image description here

Puedes acceder a él directamente:

 http://yourdomain.com/YourController/Index.js 

Debajo está la fuente:

 namespace JavaScriptViews { public class JavaScriptActionDescriptor : ActionDescriptor { private string actionName; private ControllerDescriptor controllerDescriptor; public JavaScriptActionDescriptor(string actionName, ControllerDescriptor controllerDescriptor) { this.actionName = actionName; this.controllerDescriptor = controllerDescriptor; } public override object Execute(ControllerContext controllerContext, IDictionary parameters) { return new ViewResult(); } public override ParameterDescriptor[] GetParameters() { return new ParameterDescriptor[0]; } public override string ActionName { get { return actionName; } } public override ControllerDescriptor ControllerDescriptor { get { return controllerDescriptor; } } } public class JavaScriptActionInvoker : ControllerActionInvoker { protected override ActionDescriptor FindAction(ControllerContext controllerContext, ControllerDescriptor controllerDescriptor, string actionName) { var action = base.FindAction(controllerContext, controllerDescriptor, actionName); if (action != null) { return action; } if (actionName.EndsWith(".js")) { return new JavaScriptActionDescriptor(actionName, controllerDescriptor); } else return null; } } public class JavaScriptView : IView { private string fileName; public JavaScriptView(string fileName) { this.fileName = fileName; } public void Render(ViewContext viewContext, TextWriter writer) { var file = File.ReadAllText(viewContext.HttpContext.Server.MapPath(fileName)); writer.Write(file); } } public class JavaScriptViewEngine : VirtualPathProviderViewEngine { public JavaScriptViewEngine() : this(null) { } public JavaScriptViewEngine(IViewPageActivator viewPageActivator) : base() { AreaViewLocationFormats = new[] { "~/Areas/{2}/Views/{1}/{0}.js", "~/Areas/{2}/Views/Shared/{0}.js" }; AreaMasterLocationFormats = new[] { "~/Areas/{2}/Views/{1}/{0}.js", "~/Areas/{2}/Views/Shared/{0}.js" }; AreaPartialViewLocationFormats = new [] { "~/Areas/{2}/Views/{1}/{0}.js", "~/Areas/{2}/Views/Shared/{0}.js" }; ViewLocationFormats = new[] { "~/Views/{1}/{0}.js", "~/Views/Shared/{0}.js" }; MasterLocationFormats = new[] { "~/Views/{1}/{0}.js", "~/Views/Shared/{0}.js" }; PartialViewLocationFormats = new[] { "~/Views/{1}/{0}.js", "~/Views/Shared/{0}.js" }; FileExtensions = new[] { "js" }; } public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache) { if (viewName.EndsWith(".js")) viewName = viewName.ChopEnd(".js"); return base.FindView(controllerContext, viewName, masterName, useCache); } protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath) { return new JavaScriptView(partialPath); } protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath) { return new JavaScriptView(viewPath); } } } 

Puedes invertir la sugerencia de davesw y bloquear solo .cshtml

    

Sé que este es un tema bastante antiguo, pero tengo algunas cosas que me gustaría agregar. Intenté la respuesta de davesw, pero estaba arrojando un error de 500 cuando intentaba cargar los archivos de script, así que tuve que agregar esto al web.config:

  

a system.webServer. Esto es lo que tengo, y pude hacerlo funcionar:

                      

Aquí hay más información sobre la validación: https://www.iis.net/configreference/system.webserver/validation

agregue este código en el archivo web.config dentro de la etiqueta system.web