asp.net-mvc 如何为 ASP.NET MVC 区域捆绑资源?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13335839/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 02:24:28  来源:igfitidea点击:

How to bundle resources for ASP.NET MVC areas?

asp.net-mvcasp.net-mvc-4bundleasp.net-optimization

提问by Martijn B

How would you do the resource bundling for asp.net mvc areas? Is this regulated by the ASP.NET MVC framework just like the AreaRegistrationfor routes?

您将如何为 asp.net mvc 区域进行资源捆绑?这是否像AreaRegistrationfor 路由一样由 ASP.NET MVC 框架管理?

I could make a BundleConfigclass inside the area and call this from the global BundleConfiginside the App_Startfolder but this doens't feel good to me.

我可以BundleConfig在该区域内创建一个类并从文件夹BundleConfig内的全局调用它,App_Start但这对我来说感觉不好。

I can't find any information on this subject. Any help our thoughts are appreciated.

我找不到有关此主题的任何信息。任何帮助我们的想法表示赞赏。

回答by Martijn B

I was hoping this was somehow more regulated - but after diving into the framework code the answer to this is negative.

我希望这在某种程度上更加规范 - 但在深入研究框架代码之后,答案是否定的。

What I decided to do is the following:

我决定做的是以下内容:

Solution Structure

解决方案结构

  • Areas:
    • Admin
      • RouteConfig.cs
      • BundleConfig.cs
      • AdminAreaRegistration.cs
  • 领域:
    • 行政
      • 路由配置文件
      • 捆绑配置文件
      • AdminAreaRegistration.cs

RouteConfig.cs

路由配置文件

internal static class RouteConfig
{
    internal static void RegisterRoutes(AreaRegistrationContext context)
    {
        //add routes
    }
}

BundleConfig.cs

捆绑配置文件

internal static class BundleConfig
{
    internal static void RegisterBundles(BundleCollection bundles)
    {           
        //add bundles
    }
}

AdminAreaRegistration.cs

AdminAreaRegistration.cs

public class AdminAreaRegistration : AreaRegistration
{
    public override string AreaName
    {
        get
        {
            return "Admin";
        }
    }

    public override void RegisterArea(AreaRegistrationContext context)
    {
        RegisterRoutes(context);
        RegisterBundles();
    }

    private void RegisterRoutes(AreaRegistrationContext context)
    {
        RouteConfig.RegisterRoutes(context);
    }

    private void RegisterBundles()
    {
        BundleConfig.RegisterBundles(BundleTable.Bundles);            
    }       
}

回答by Nick

Your question implies that you have separate scripts & css folders for each area? This is unconventional (though perfectly plausible). Or perhaps you have a single scripts folder at the route level and you have split that into sub folders for each Area? Either way you will have to do something only slightly different to get Area specific bundles.

您的问题意味着每个区域都有单独的脚本和 css 文件夹?这是非常规的(尽管完全合理)。或者您可能在路线级别有一个脚本文件夹,并且您已将其拆分为每个区域的子文件夹?无论哪种方式,您都必须做一些稍微不同的事情才能获得特定于区域的捆绑包。

MVC4 applications come with a static BundleConfigclass that lives in the App_Start folder. The bundle is then initialized from the Global.asax. If you are not working with a MVC4 project either upgrade or just start an out of the box MVC4 project to observe the layout of these files.

MVC4 应用程序带有一个BundleConfig位于 App_Start 文件夹中的静态类。然后从 Global.asax 初始化包。如果您不使用 MVC4 项目,请升级或启动开箱即用的 MVC4 项目以观察这些文件的布局。

Bundles are configured simply by declaring a virtual path, (from which the bundle can be referenced) then specifying the files you wish to be bundled. The files to be bundled can be specified by listing the filename explicitly, filename character matching, or specifying a directory in which all files should be included.

捆绑包的配置只需声明一个虚拟路径(可以从中引用捆绑包)然后指定您希望捆绑的文件。要捆绑的文件可以通过明确列出文件名、文件名字符匹配或指定应包含所有文件的目录来指定。

To begin with, I would just use this global BundleConfigto specify bundles for all of your areas. If this does not scale for you or becomes unwieldy, you can always break it out later.

首先,我只会使用这个全局BundleConfig变量来为您的所有区域指定包。如果这不适合您或变得笨拙,您可以稍后将其分解。

Specify which files should be included. You should prefix the bundle's virtual path with the Area that it is for. Then it will be easy to reference using the Area name from your views - most likely your _Layout.cshtml.

指定应包含哪些文件。您应该在包的虚拟路径前面加上它所在的区域。然后使用视图中的区域名称将很容易引用 - 很可能是您的_Layout.cshtml.

For example, here we have two Areas each with distinct scripts: Userand Group.

例如,这里我们有两个区域,每个区域都有不同的脚本:UserGroup

App_Start/BundleConfig.cs

App_Start/BundleConfig.cs

public class BundleConfig
{
    public static void RegisterBundles(BundleCollection bundles)
    {
        /// Bundle For User Area
        bundles.Add(new ScriptBundle("~/user/bundles/scripts").Include(
                    "~/Scripts/User/myuserscript1.js",
                    "~/Scripts/User/myuserscript2.js"));

        /// Bundle For Group Area
        bundles.Add(new ScriptBundle("~/group/bundles/scripts").Include(
                    "~/Scripts/Group/mygroupscript1.js",
                    "~/Scripts/Group/mygroupscript2.js"));
    }
}

You can then use the Scripts.Render()on your main _Layout.cshtml to render the correct Area bundle, depending on which area the user is currently viewing. To do this you first need to get the current Area like so:

然后,您可以使用Scripts.Render()主 _Layout.cshtml 上的 来呈现正确的区域包,具体取决于用户当前正在查看的区域。为此,您首先需要像这样获取当前区域:

Views/Shared/_Layout.cshtml:

视图/共享/_Layout.cshtml:

<head>
    @{
        var currentArea = (ViewContext.RouteData.DataTokens["area"]
                              ?? String.Empty).ToString().ToLower();
    }
    @Scripts.Render("~/" + currentArea + "/bundles/scripts")
</head>

EDIT

编辑

If you really want to manage your bundle from within your Area, then the Area registration would be a good place to do so. The BundleTable static property referenced in the BundleConfig is global so it can be referenced anywhere. This code compiles but I haven't tested it. It is for an Area called Test:

如果你真的想在你的区域内管理你的包,那么区域注册将是一个很好的地方。BundleConfig 中引用的 BundleTable 静态属性是全局的,因此可以在任何地方引用。这段代码可以编译,但我还没有测试过。它用于名为 Test 的区域:

Areas/Test/TestAreaRegistration.cs

区域/测试/TestAreaRegistration.cs

    public override void RegisterArea(AreaRegistrationContext context)
    {
        context.MapRoute(
            "Test_default",
            "Test/{controller}/{action}/{id}",
            new { action = "Index", id = UrlParameter.Optional }
        );

        BundleTable.Bundles.Add(new Bundle("~/test/bundles/scripts").Include(
                    "~/Areas/Test/Scripts/jquery.js"));
    }