javascript MVC Razor,包含来自另一个项目的 JS / CSS 文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11842988/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
MVC Razor, Include JS / CSS files from another project
提问by Martin
I've got a C# MVC project that uses Razor syntax.
To be able to reuse some code, I want to put some of my JavaScript and CSS files in a different project and include them somehow.
This is how my scripts are included at the moment:
我有一个使用 Razor 语法的 C# MVC 项目。
为了能够重用一些代码,我想将一些 JavaScript 和 CSS 文件放在不同的项目中并以某种方式包含它们。
目前我的脚本是这样包含的:
<script src="@Url.Content("~/Scripts/bootstrap-typeahead.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/bootstrap-dropdown.js")" type="text/javascript"></script>
At the moment, the scripts are in the same project as the cshtml file but they should be placed in the Common.Web project instead...
What I want to do is this (doesn't work though):
目前,脚本与 cshtml 文件在同一个项目中,但它们应该放在 Common.Web 项目中......
我想做的是这个(虽然不起作用):
<script src="@Url.Content("Common.Web/Scripts/bootstrap-typeahead.js")" type="text/javascript"></script>
<script src="@Url.Content("Common.Web/Scripts/bootstrap-dropdown.js")" type="text/javascript"></script>
回答by retslig
I do this very thing. However I embed the Javascript files and other content in another DLL and then call them from my razor syntax like so. Here is the code I use. In the View: Script example:
我做这件事。但是,我将 Javascript 文件和其他内容嵌入到另一个 DLL 中,然后像这样从我的 razor 语法中调用它们。这是我使用的代码。在视图:脚本示例中:
<script [email protected]("GetEmbeddedResource", "Shared", new { resourceName = "Namespace.Scripts.jquery.qtip.min.js", pluginAssemblyName = @Url.Content("~/bin/Namespace.dll") }) type="text/javascript" ></script>
Image Example:
图像示例:
@Html.EmbeddedImage("corporate.gif", new { width = 150, height = 50})
Here is my helper methods:
这是我的辅助方法:
public static MvcHtmlString EmbeddedImage(this HtmlHelper htmlHelper, string imageName, dynamic htmlAttributes)
{
UrlHelper url = new UrlHelper(HttpContext.Current.Request.RequestContext);
var anchor = new TagBuilder("img");
anchor.Attributes["src"] = url.Action("GetEmbeddedResource", "Shared",
new
{
resourceName = "Namespace.Content.Images." + imageName,
pluginAssemblyName = url.Content("~/bin/Namespace.dll")
});
if (htmlAttributes != null)
{
string width = "";
string height = "";
PropertyInfo pi = htmlAttributes.GetType().GetProperty("width");
if (pi != null)
width = pi.GetValue(htmlAttributes, null).ToString();
pi = htmlAttributes.GetType().GetProperty("height");
if (pi != null)
height = pi.GetValue(htmlAttributes, null).ToString();
if (!string.IsNullOrEmpty(height))
anchor.Attributes["height"] = height;
if (!string.IsNullOrEmpty(width))
anchor.Attributes["width"] = width;
}
return MvcHtmlString.Create(anchor.ToString());
}
Lastly my shared Controller:
最后我的共享控制器:
[HttpGet]
public FileStreamResult GetEmbeddedResource(string pluginAssemblyName, string resourceName)
{
try
{
string physicalPath = Server.MapPath(pluginAssemblyName);
Stream stream = ResourceHelper.GetEmbeddedResource(physicalPath, resourceName);
return new FileStreamResult(stream, GetMediaType(resourceName));
//return new FileStreamResult(stream, GetMediaType(tempResourceName));
}
catch (Exception)
{
return new FileStreamResult(new MemoryStream(), GetMediaType(resourceName));
}
}
private string GetMediaType(string fileId)
{
if (fileId.EndsWith(".js"))
{
return "text/javascript";
}
else if (fileId.EndsWith(".css"))
{
return "text/css";
}
else if (fileId.EndsWith(".jpg"))
{
return "image/jpeg";
}
else if (fileId.EndsWith(".gif"))
{
return "image/gif";
}
else if (fileId.EndsWith(".png"))
{
return "image/png";
}
return "text";
}
Resource Helper:
资源助手:
public static class ResourceHelper
{
public static Stream GetEmbeddedResource(string physicalPath, string resourceName)
{
try
{
Assembly assembly = PluginHelper.LoadPluginByPathName<Assembly>(physicalPath);
if (assembly != null)
{
string tempResourceName = assembly.GetManifestResourceNames().ToList().FirstOrDefault(f => f.EndsWith(resourceName));
if (tempResourceName == null)
return null;
return assembly.GetManifestResourceStream(tempResourceName);
}
}
catch (Exception)
{
}
return null;
}
}
Plugin Helper
插件助手
public static T LoadPluginByPathName<T>(string pathName)
{
string viewType = typeof(T).GUID.ToString();
if (HttpRuntime.Cache[viewType] != null)
return HttpRuntime.Cache[viewType] is T ? (T)HttpRuntime.Cache[viewType] : default(T);
object plugin = Assembly.LoadFrom(pathName);
if (plugin != null)
{
//Cache this object as we want to only load this assembly into memory once.
HttpRuntime.Cache.Insert(viewType, plugin);
return (T)plugin;
}
return default(T);
}
Remember that I am using these as embedded content!
请记住,我将这些用作嵌入内容!
回答by wal
To my knowledge you can't do this as the path would lie outside of the website.
据我所知,您不能这样做,因为路径位于网站之外。
You can however do the following:
但是,您可以执行以下操作:
1) Put all the scripts you want to share in Common.Web\Scripts
2) For each script file in your Web application 'Add as Link'to your Common.Web Scripts (you don't even need to do this step; it is however nice to see what scripts your web app uses in VS)
3) Add a post-build event to your Web application that copies the scripts from Common.Web\Scripts to your WebApp\Scripts folder:
1) 将您想要共享的所有脚本放在 Common.Web\Scripts
2) 对于您的 Web 应用程序中的每个脚本文件,“添加为链接”到您的 Common.Web 脚本(您甚至不需要执行此步骤;它但是很高兴看到您的 Web 应用程序在 VS 中使用了哪些脚本)
3) 将构建后事件添加到您的 Web 应用程序,将脚本从 Common.Web\Scripts 复制到您的 WebApp\Scripts 文件夹:
copy $(ProjectDir)..\Common.Web\Scripts* $(ProjectDir)\Scripts
复制 $(ProjectDir)..\Common.Web\Scripts* $(ProjectDir)\Scripts
so from your perspective in Visual Studio you will only have a single place to update your .js files that can be used by multiple projects.
因此,从您在 Visual Studio 中的角度来看,您将只有一个位置来更新可供多个项目使用的 .js 文件。
回答by Nikola Radosavljevi?
Instead of using Url
helper use relative addressing. What you tried to do makes no sense, as helper is used to resolve paths relative to it's project.
而不是使用Url
助手使用相对寻址。您尝试做的事情毫无意义,因为 helper 用于解析与其项目相关的路径。
Since you are trying to use resources of another project, it's ok to assume that you know upfront where you're going to deploy each project. Even though I don't like this practice, I can think of a pragmatic solution for this.
由于您正在尝试使用另一个项目的资源,因此可以假设您预先知道要部署每个项目的位置。尽管我不喜欢这种做法,但我可以为此想到一个务实的解决方案。
If your two applications are at urls:
如果您的两个应用程序位于 urls:
http://www.mysite.com/app1
http://www.mysite.com/Common.Web
you could address like this:
你可以这样解决:
<script src="@Url.Content("~")/../Common.Web/Scripts/bootstrap-typeahead.js")" type="text/javascript"></script>
meaning, resolve my app root folder, go up a level, and go down rest of the path.
意思是,解析我的应用程序根文件夹,向上一级,然后向下走其余的路径。
回答by Hamish
I just found this question while looking for the same answer. Thanks to the previous posters, who made it clear that this cannot be done using Visual Studio alone: you will alwaysend up with a copy of the original file, or an incomplete set of shipping files.
我刚刚在寻找相同答案时发现了这个问题。由于以前的海报,谁明确表示,这不能单独使用Visual Studio来完成:你会永远结束了原始文件的副本,或集海运的文件不完整的。
I do not wish to reinvent the wheel whenever I have simple common functionality, so I have a folder for common scripts on my hard drive: /Common/Javascript
每当我有简单的通用功能时,我都不想重新发明轮子,所以我的硬盘驱动器上有一个用于常见脚本的文件夹:/Common/Javascript
My web project is located in: /ProjectName
我的网络项目位于:/ProjectName
so my common scripts lie outside my web project.
所以我的常用脚本位于我的网络项目之外。
I solved this via source control. Most source control repositories will have the functionality to show a file in another directory. My steps were:
我通过源代码管理解决了这个问题。大多数源代码控制存储库都具有在另一个目录中显示文件的功能。我的步骤是:
- Create empty folder under my VS project: /ProjectName/Scripts/Common
- Committed the empty folder to source control
- Using Subversion (my source control), I set up an "extern" so that my common file was linked to the new folder. Other source control software may call this a "link" or some other such thing.
- Updated the new folder, and my common Javascript files came in, and could now be added to my web project in Visual Studio.
- 在我的 VS 项目下创建空文件夹:/ProjectName/Scripts/Common
- 将空文件夹提交给源代码管理
- 使用 Subversion(我的源代码控制),我设置了一个“extern”,以便将我的公共文件链接到新文件夹。其他源代码控制软件可能将其称为“链接”或其他类似的东西。
- 更新了新文件夹,我的常用 Javascript 文件进来了,现在可以添加到我在 Visual Studio 中的 web 项目中。
Obviously, I tested this by changing the files within Visual Studio and committing them. The changes were indeed reflected in the original files, sitting in /Common/Javascript.
显然,我通过更改 Visual Studio 中的文件并提交它们来对此进行了测试。更改确实反映在原始文件中,位于 /Common/Javascript 中。
I can now simply add an extern to any other web project which needs to use the same functionality: though, of course, changing those files comes with additional risk now, as I may unexpectedly break other projects which use them. Though I can configure an extern to use a specific revision of a file, that's not what I want to do at this point; I shall await such complexity as and when it occurs.
我现在可以简单地向任何其他需要使用相同功能的 Web 项目添加一个 extern:当然,现在更改这些文件会带来额外的风险,因为我可能会意外地破坏使用它们的其他项目。虽然我可以配置 extern 以使用文件的特定修订版,但这不是我现在想要做的;当它发生时,我将等待这种复杂性。