将视图特定的javascript文件放在ASP.NET MVC应用程序中的最佳位置(哪个文件夹等)是什么?
为了保持我的项目井然有序,我真的很想能够将它们与视图的.aspx文件并排放置,但是我没有找到一种很好的方法来引用它们而不暴露〜/ Views/Action /文件夹结构.让文件夹结构的细节泄漏真的是一件坏事吗?
另一种方法是将它们放在〜/ Scripts或〜/ Content文件夹中,但这是一个小小的烦恼,因为现在我不得不担心文件名冲突.不过,如果这是"正确的事情",我可以克服这种烦恼.
老问题,但我想把我的答案包括在内,其他任何人都在寻找它.
我也想在views文件夹下查看我的视图特定的js/css文件,这是我的做法:
在/ Views根目录中的web.config文件夹中,您需要修改两个部分以使Web服务器能够提供文件:
然后从您的视图文件中,您可以像您期望的那样引用网址:
@Url.Content("~/Views//somefile.css")
这将允许提供.js和.css文件,并将禁止提供任何其他内容.
实现这一目标的一种方法是提供自己的ActionInvoker
.使用下面的代码,您可以添加到控制器的构造函数:
ActionInvoker = new JavaScriptActionInvoker();
现在,每当您.js
在视图旁边放置文件时:
您可以直接访问它:
http://yourdomain.com/YourController/Index.js
以下是来源:
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, IDictionaryparameters) { 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); } } }