[英]Using Javascript files from a Class Library in an ASP.NET MVC project
假設我有一個包含 HelloWorld.js 文件的類庫。
該文件包含幾個 javascript 函數,例如:
function Hello_alert() {
alert("Hello World!!");
}
和
function Hello_console() {
console.log("Hello World!!");
}
我想讓我可以單獨訪問 HelloWorld.js 文件中的函數,在ASP.NET MVC頁面上,比如 Home 文件夾中的 Index.cshtml。 (否則,我很樂意訪問 .js 文件。)
我已經將 .js 更改為 EmbeddedResource 並將其添加到程序集中,如下所示:
[assembly: WebResource("JSLibrary.Scriptss.HelloWorld.js", "application/x-javascript")]
; 在我的 MVC 項目中引用了 DLL,並且 DLL 命名空間顯示在 Intellisense 上,所以我猜它是正確鏈接的。
現在,我一整天都在不停地谷歌搜索,我找到了一種解決方案,可以滿足我的需要,但它適用於Web Forms ,使用 Page.ClientScript 將腳本注冊到頁面本身,這允許人們調用該頁面上 .js 文件中的函數。 這幾乎就是我想要做的,除了我在MVC 中需要它,它不使用這樣的“Page”類。
我發現的 closes 等價物與捆綁包有關,但我找不到任何可以切實遵循的教程。
所以,我的問題是,我如何以某種方式從 DLL 注冊 Javascript 文件,以便我能夠從ASP.NET MVC項目中調用它們?
- - - - 更新: - - - - -
按照我上面鏈接的教程,我的 DLL 有一個帶有方法的類,用於在腳本管理器中注冊腳本,它作為參數接收。 像這樣
public static void includeHelloWorld(ClientScriptManager manager)
{
manager.RegisterClientScriptResource(typeof(JSLibrary.JSAccess), ScriptPath_HelloWorld);
}//JSLibrary being the DLL namespace and JSAccess being the class
然后,在主項目中,使用Web Forms ,您可以調用該方法並將其傳遞給當前頁面的 ClientScript 屬性,我假設腳本在其中注冊。 像這樣:
protected void Page_Load(object sender, EventArgs e)
{
JSLibrary.JSAccess.includeHelloWorld(Page.ClientScript);
}
我試過了,它適用於Web Forms 。 我需要MVC中的 Page.ClientScript 等價物,我可以將其發送到 DLL 中的方法,該方法接受 ClientScriptManager。
謝謝
好的,我想通了。
由於沒有人回應,我想我會回來與全世界分享我的問題的解決方案,以防其他人發現它有用。
顯然,MVC 有這個Blundles功能,允許您捆綁JS 腳本以供將來使用。 Bundle使用Virtual Paths來訪問它們的文件,但是默認的Virtual Paths不能訪問 DLLs(至少不是其中的文件),所以我們必須在我們的 DLL 中創建一個自定義的Virtual Path 。 在主程序中注冊這個VP后,我們可以訪問 DLL 上的文件,就像它們在我們的主程序中一樣,因此,將腳本包含在我們的包中。
請注意,這可能不是最好或最有效的方法,只是我拼湊起來的似乎有效的方法。
好的,這是我們如何做到的:
首先,安裝以下NuGet 包:
Install-Package EmbeddedResourceVirtualPathProvider
然后,在我們的 DLL 中,確保您的 .js 文件被設置為嵌入資源。 接下來我們在命名空間的根目錄中創建一個類,它將成為我們的虛擬路徑提供者和虛擬文件。 基本上,只需將此代碼放在命名空間的根目錄中:
public class EmbeddedVirtualPathProvider : VirtualPathProvider
{
private readonly Assembly assembly = typeof(EmbeddedVirtualPathProvider).Assembly;
private readonly string[] resourceNames;
public EmbeddedVirtualPathProvider()
{
this.resourceNames = assembly.GetManifestResourceNames();
}
private bool IsEmbeddedResourcePath(string virtualPath)
{
var checkPath = VirtualPathUtility.ToAppRelative(virtualPath);
var resourceName = this.GetType().Namespace + "." + checkPath.Replace("~/", "").Replace("/", ".");
return this.resourceNames.Contains(resourceName);
}
public override bool FileExists(string virtualPath)
{
return IsEmbeddedResourcePath(virtualPath) || base.FileExists(virtualPath);
}
public override VirtualFile GetFile(string virtualPath)
{
if (IsEmbeddedResourcePath(virtualPath))
{
return new EmbeddedVirtualFile(virtualPath);
}
return base.GetFile(virtualPath);
}
public override CacheDependency GetCacheDependency(string virtualPath, IEnumerable virtualPathDependencies, DateTime utcStart)
{
if (IsEmbeddedResourcePath(virtualPath))
{
return null;
}
return base.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart);
}
}
public class EmbeddedVirtualFile : VirtualFile
{
private readonly string virtualPath;
private readonly Assembly assembly;
public EmbeddedVirtualFile(string virtualPath)
: base(virtualPath)
{
this.assembly = this.GetType().Assembly;
this.virtualPath = VirtualPathUtility.ToAppRelative(virtualPath);
}
public override System.IO.Stream Open()
{
var resourceName = this.GetType().Namespace + "." + virtualPath.Replace("~/", "").Replace("/", ".");
return assembly.GetManifestResourceStream(resourceName);
}
}
這是上面代碼中的兩個類。
您將需要包含一些庫,例如
using System.Reflection;
using System.Web.Hosting;
using System.Web;
using System.Web.Caching;
using System.Collections;
現在,在我們的主項目中,我們將注冊這個Virtual Path 。 如果您沒有在 main 中引用DLL :在解決方案資源管理器中,在您的 Main 項目下,右鍵單擊 References -> Add Reference 並選擇您的 DLL。
為了注冊VP ,只需在主項目的 Global.asax 文件中添加這一行(在Application_Start() 方法的最頂部):
HostingEnvironment.RegisterVirtualPathProvider(new EmbeddedVirtualPathProvider());
您需要在 Global.asax 中包含:
using System.Web.Hosting;
using <your dll namespace>;
using System.Web.Hosting;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
現在將腳本添加到包中。 App_Start 文件夾內應該有一個 BundleConfig.cs 文件。 在 RegisterBundles 方法中,您可以只寫:
bundles.Add(new ScriptBundle("~/bundles/external/helloworld").Include(
"~/Scripts/HelloWorld.js"));
其中第一個參數(“~/bundles/external/helloworld”)可以是你在 ~/ 之后想要的任何東西,第二個參數(“~/Scripts/HelloWorld.js”)必須是你的腳本中的路徑動態鏈接庫。
最后,讓我們在視圖中渲染腳本。 選擇一個視圖,比如 Index.cshtml,然后只包含以下行:
@Scripts.Render("~/bundles/external/helloworld")
參數是您在創建包時命名的任何內容,現在它應該可以工作了!
如果您實施 Zidd 的技術並獲得“無法加載資源:服務器響應狀態為 404(未找到) ”,請添加以下行:
BundleTable.EnableOptimizations = true;
在BundleConfig.RegisterBundles
方法的末尾。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.