在 ASP.NET MVC 项目中使用类库中的 Javascript 文件

Zid*_*idd 5 javascript asp.net model-view-controller dll class-library

假设我有一个包含 HelloWorld.js 文件的类库。

该文件包含几个 JavaScript 函数,例如:

function Hello_alert() {
   alert("Hello World!!");
}
Run Code Online (Sandbox Code Playgroud)

function Hello_console() {
   console.log("Hello World!!");
}
Run Code Online (Sandbox Code Playgroud)

我想要这样我就可以在ASP.NET MVC页面上单独访问 HelloWorld.js 文件内的函数,例如 Home 文件夹内的 Index.cshtml。(如果做不到这一点,我会很高兴访问 .js 文件。)

我已经将 .js 更改为 EmbeddedResource 并将其添加到程序集中,如下所示:

[assembly: WebResource("JSLibrary.Scriptss.HelloWorld.js", "application/x-javascript")]
Run Code Online (Sandbox Code Playgroud)

; 在我的 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
Run Code Online (Sandbox Code Playgroud)

然后,在主项目中,使用Web Forms,您可以调用该方法并向其传递当前页面的 ClientScript 属性,我假设脚本在其中注册。就像这样:

protected void Page_Load(object sender, EventArgs e)
    {
        JSLibrary.JSAccess.includeHelloWorld(Page.ClientScript);
    }
Run Code Online (Sandbox Code Playgroud)

我已经尝试过了,它可以在Web Forms上运行。我需要MVC中的 Page.ClientScript 的等效项,我可以将其发送到 DLL 中接受 ClientScriptManager 的方法。

谢谢

Zid*_*idd 7

好吧,我想通了。

由于没有人回复,我想我会回来并与世界分享我的问题的解决方案,以防万一其他人发现它有用。

显然,MVC 具有Blundles功能,允许您捆绑JS 脚本等内容以供将来使用。捆绑包使用虚拟路径来访问其文件,但默认的虚拟路径无法访问 DLL(至少不能访问其中的文件),因此我们必须在 DLL 中创建自定义虚拟路径。在主程序中注册该VP后,我们可以访问 DLL 上的文件,就像它们在我们的主程序上一样,从而将脚本包含在我们的包中。

请注意,这可能不是最好或最有效的方法,只是我拼凑起来的似乎有效的方法。


好的,我们是这样做的:

首先,安装以下NuGet 包

Install-Package EmbeddedResourceVirtualPathProvider
Run Code Online (Sandbox Code Playgroud)

然后,在我们的 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是上面代码中的两个类。

您将需要包含一些库,例如

using System.Reflection;
using System.Web.Hosting;
using System.Web;
using System.Web.Caching;
using System.Collections;
Run Code Online (Sandbox Code Playgroud)

现在,在我们的主项目中,我们将注册这个虚拟路径。如果您尚未在主项目中引用DLL :在解决方案资源管理器中的主项目下,右键单击“引用”->“添加引用”并选择您的 DLL。

为了注册VP,只需在主项目的 Global.asax 文件中添加以下行(在Application_Start() 方法的最顶部):

HostingEnvironment.RegisterVirtualPathProvider(new EmbeddedVirtualPathProvider());
Run Code Online (Sandbox Code Playgroud)

您需要在 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;
Run Code Online (Sandbox Code Playgroud)

现在将脚本添加到捆绑包中。App_Start 文件夹内应该有一个 BundleConfig.cs 文件。在 RegisterBundles 方法中,您可以编写:

bundles.Add(new ScriptBundle("~/bundles/external/helloworld").Include(
                    "~/Scripts/HelloWorld.js"));
Run Code Online (Sandbox Code Playgroud)

其中第一个参数(“~/bundles/external/helloworld”)可以是 ~/ 之后的任何内容,第二个参数(“~/Scripts/HelloWorld.js”)必须是脚本内部的路径DLL。

最后,让我们在视图中渲染脚本。选择一个视图,例如 Index.cshtml,然后只包含以下行:

@Scripts.Render("~/bundles/external/helloworld")
Run Code Online (Sandbox Code Playgroud)

参数是您在创建捆绑包时命名的任何参数,现在它应该可以工作了!