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

标签 javascript asp.net model-view-controller dll class-library

假设我有一个包含 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 中:
[assembly: WebResource("JSLibrary.Scriptss.HelloWorld.js", "application/x-javascript")]
;在我的 MVC 项目中引用了 DLL,并且 DLL 命名空间出现在 Intellisense 上,所以我猜它是正确链接的。
现在,我一整天都在不停地谷歌上搜索,我找到了一个 solution that kinda does what I need , 但它适用于 网络表格 ,使用 Page.ClientScript 将脚本注册到页面本身,这允许调用该页面上 .js 文件中的函数。这几乎就是我想要做的,除了我在 中需要它。 MVC ,它不使用这样的“页面”类。
我发现的关闭等效项与捆绑包有关,但我找不到任何可以遵循的教程。
再次,我的问题是,我如何以某种方式从 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
然后,在主项目中,使用 网络表格 ,您可以调用该方法并将当前页面的 ClientScript 属性传递给它,我假设脚本在此注册。像这样:
protected void Page_Load(object sender, EventArgs e)
    {
        JSLibrary.JSAccess.includeHelloWorld(Page.ClientScript);
    }
我已经尝试过了,它适用于 网络表格 .我需要 中的 Page.ClientScript 的等效项MVC ,我可以发送到 DLL 中接受 ClientScriptManager 的方法。
谢谢

最佳答案

好的,我想通了。

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

显然,MVC 有这个 杂乱无章 允许您捆绑,除其他外, 的功能JS 脚本 以备将来使用。 捆绑 使用 虚拟路径 访问他们的文件,但默认 虚拟路径 无法访问 DLL(至少不能访问其中的文件),因此我们必须创建自定义 虚拟路径 在我们的 DLL 中。注册后副总裁 在主程序中,我们可以访问 DLL 上的文件,就像它们在我们的主程序中一样 因此,将脚本包含在我们的包中。

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

好的,这就是我们的做法:

首先,安装以下 NuGet package :

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;

现在,在我们的 主要项目 , 我们要注册这个 虚拟路径 .如果您还没有引用 动态链接库 在您的主项目中:在解决方案资源管理器中,在您的主项目下,右键单击“引用”->“添加引用”并选择您的 DLL。

为了注册副总裁 ,只需在主项目的 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") 必须是脚本内的路径动态链接库。

最后,让我们在 View 中渲染脚本。选择一个 View ,比如 Index.cshtml,然后只包含以下行:
@Scripts.Render("~/bundles/external/helloworld")

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

关于javascript - 在 ASP.NET MVC 项目中使用类库中的 Javascript 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51772644/

相关文章:

javascript - 增加 UP 大小的动态 div 高度

c# - 如何对调用 Action 的 HTML Helper 进行单元测试?

jquery - 缩小没有生成缩小版本

c# - 需要自定义 .NET 应用程序搜索解决方案

.net - Asp.Net MVC 路由表和 Controller 操作

javascript - 我可以使用新的 'controller as' 语法将 Typescript 类用作 AngularJS Controller 吗

python - Django 的 html 模板替代品是什么?

javascript - 在移动浏览器上自动播放视频元素

javascript - 'router-outlet' 不是 Angular2 的已知元素

javascript - 使用 ng-click 将动态值传递给 Angular 函数