簡體   English   中英

在 ASP.NET MVC 項目中使用類庫中的 Javascript 文件

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM