Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where to put view-specific javascript files in an ASP.NET MVC application?

Tags:

asp.net-mvc

What is the best place (which folder, etc) to put view-specific javascript files in an ASP.NET MVC application?

To keep my project organized, I'd really love to be able to put them side-by-side with the view's .aspx files, but I haven't found a good way to reference them when doing that without exposing the ~/Views/Action/ folder structure. Is it really a bad thing to let details of that folder structure leak?

The alternative is to put them in the ~/Scripts or ~/Content folders, but is a minor irritation because now I have to worry about filename clashes. It's an irritation I can get over, though, if it is "the right thing."

like image 849
Erv Walter Avatar asked Mar 03 '09 02:03

Erv Walter


People also ask

Where do I put JavaScript code in MVC?

The recommended approach is to put in a separate JavaScript file or inside a section defined in Layout page. A section can be added in the MVC Layout page using @RenderSection() directive. For example, we can define a section in Layout page under <head> tag for scripts like below.

Where should I put my JavaScript files?

To place JavaScript in an HTML file, use the <script>… </script> tag. You can place the <script> tags, containing your JavaScript, anywhere within your web page, but it is normally recommended that you should keep it within the <head> tags.

HOW include JS file in ASP NET MVC?

Go to Views -> Shared -> _Layout. cshtml file and add the render code. Make sure to register the custom javascript file after the jquery bundle since we are going to use jquery inside our js file. Otherwise we will get a jquery error and also register this before the script RenderSection.

How can add JavaScript file in ASP.NET project?

Simply open the file in the browser, press "view source" and use the JS path in the URL to see if it opens. Your syntax is (more or less) correct.


2 Answers

Old question, but I wanted to put my answer incase anyone else comes looking for it.

I too wanted my view specific js/css files under the views folder, and here's how I did it:

In the web.config folder in the root of /Views you need to modify two sections to enable the webserver to serve the files:

    <system.web>         <httpHandlers>             <add path="*.js" verb="GET,HEAD" type="System.Web.StaticFileHandler" />             <add path="*.css" verb="GET,HEAD" type="System.Web.StaticFileHandler" />             <add path="*" verb="*" type="System.Web.HttpNotFoundHandler"/>         </httpHandlers>         <!-- other content here -->     </system.web>      <system.webServer>         <handlers>             <remove name="BlockViewHandler"/>             <add name="JavaScript" path="*.js" verb="GET,HEAD" type="System.Web.StaticFileHandler" />             <add name="CSS" path="*.css" verb="GET,HEAD" type="System.Web.StaticFileHandler" />             <add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />         </handlers>         <!-- other content here -->     </system.webServer> 

Then from your view file you can reference the urls like you expect:

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

This will allow serving of .js and .css files, and will forbid serving of anything else.

like image 91
davesw Avatar answered Sep 27 '22 22:09

davesw


One way of achieving this is to supply your own ActionInvoker. Using the code included below, you can add to your controller's constructor:

ActionInvoker = new JavaScriptActionInvoker(); 

Now, whenever you place a .js file next to your view:

enter image description here

You can access it directly:

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

Below is the source:

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<string, object> 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);         }     } } 
like image 41
Kirk Woll Avatar answered Sep 27 '22 23:09

Kirk Woll