使用IIS时,如何格式化MVC中RequireJS的依赖项名称?

时间:2014-01-16 23:38:58

标签: asp.net-mvc asp.net-mvc-4 iis requirejs

我关注了一个现已删除的博客(请参阅下面的所有代码,了解我的所作所为),以便在MVC中创建基本的RequireJS结构。在IIS Express中,一切都按预期工作。在IIS中时,找不到核心模块。两者之间的唯一区别(IIS和IIS Express)是Map Paths显示IIS的wwwroot以及我为IIS Express开发的实际文件路径。以下是我所指的构建require脚本的代码。

        if (File.Exists(helper.ViewContext.HttpContext.Server.MapPath(Path.Combine(jsLocation, module + ".js"))))
        {
            require.AppendLine("require( [ \"" + jsLocation + core + "\" ], function() {");
            require.AppendLine("    require( [ \"" + module + "\"] );");
            require.AppendLine("});");
        }

将具有依赖项名称的上述AppendLines替换为以下结构。 VirtualPathUtility就是所需要的。

require.AppendLine("require( [ \"" + VirtualPathUtility.ToAbsolute("~/" + jsLocation + core) + "\" ], function() {");

结束解决方案

这是我的文件结构(根项目MVCTesting)

Scripts
   require.js
   -AMD
      core.js
      -Views
         -JQuery
          AMDRequire.js

如果我的layout.cshtml包含以下格式的require(注意:由于某种原因,它允许我将.js放在模块名称中,不确定那个。)

    <script type="text/javascript">
        require( [ "/Scripts/AMD/core.js" ], function() {});
    </script>

在MVC和使用IIS时,依赖项名称的格式(“/Scripts/AMD/core.js”)应该正确加载?我的项目名称是MVCTesting,所以我有尝试了“/ MVCTesting/Scripts/AMD/core.js”以及手动正斜杠的各种组合而没有任何运气。

更新

AMDRequire.js中的代码

alert("HELLO AMD WORLD!");

IIS Express

Full URL: http://localhost:55916/jquery/amdrequire
Project Url (Project Properties): http://localhost:55916/
Results: Displays alert message HELLO AMD WORLD!

IIS

Full URL: http://localhost/MVCTesting/jquery/amdrequire
Project URL (Project Properties): http://localhost/MVCTesting
Results: No display message, I am assuming because the js file was not file

最终代码(注意,我建议使用AngularJS)

    #region DOJO AMD Loader
    /// <summary>
    /// Create the javascript required to use DOJO while following AMD specifications
    /// 
    /// Just place @Html.DOJOAMDLoader() in your Layout or other cshtml that you want to use 
    /// this and it will populate the dojoConfig, the script include for dojo, and the current 
    /// page's AMD JavaScript file.
    /// </summary>
    /// <param name="helper"></param>
    /// <param name="bsndm"></param>
    /// <param name="btsRoot"></param>
    /// <returns></returns>
    public static MvcHtmlString DOJOAMDLoader(this HtmlHelper helper)
    {
        var action = helper.ViewContext.RouteData.Values["action"].ToString().ToLower();
        var controller = helper.ViewContext.RouteData.Values["controller"].ToString().ToLower();

        return helper.CreateDOJORequire(controller, action,
            BuildInitJsLogging(ConfigurationManager.AppSettings["JavascriptLoggingLevel"],
                               ConfigurationManager.AppSettings["JavascriptLoggingAllowDisplayOverride"]));
    }

    /// <summary>
    /// Kick off the custom js logging, display is handled inside the logging JS
    /// </summary>
    /// <param name="logLevel">The state of the js log (expects Off, On, File)</param>
    /// <param name="displayOverride">For failure to log to files, display to screen override</param>
    /// <returns></returns>
    private static string BuildInitJsLogging(string logLevel, string displayOverride)
    {
        //This is not used for non system pages or test pages
        if (logLevel == null)
        {
            return null;
        }

        var updateVariable = new StringBuilder();

        updateVariable.AppendLine("require(['logging', 'dojo/domReady!'], function (logging) {");
        updateVariable.AppendFormat("logging.initJsLogging('{0}','{1}');", logLevel, displayOverride);
        updateVariable.AppendLine("});");

        return updateVariable.ToString();
    }

    /// <summary>
    /// This builds the script that will be placed on the page for DOJOAMDLoader
    /// 
    /// Included scripts will be the dojoConfig, the script include for dojo, and the currnet
    /// page's AMD JavaScript file.
    /// </summary>
    /// <param name="helper"></param>
    /// <param name="controller"></param>
    /// <param name="action"></param>
    /// <returns></returns>
    private static MvcHtmlString CreateDOJORequire(this HtmlHelper helper, string controller
        , string action, string javascriptLogging)
    {
        //Don't build require string if there is not an amd script
        if (!File.Exists(helper.ViewContext.HttpContext.Server.MapPath(
            GetAbsolutePath(Path.Combine("Scripts", "AMD", "Views", controller, action + ".js")))))
        {
            return null;
        }

        //TODO:HP:At the end of the project before going live, merge these
        //into as few AppendLine statements as possible.

        var require = new StringBuilder();

        require.AppendLine("<script>");
        require.AppendLine("dojoConfig = {");
        require.AppendLine("    async: true,");
        require.AppendLine("    packages: [");
        require.AppendLine(BuildPackageScriptText("jquery", "Scripts/ThirdParty/jQuery", "jquery-1.9.1", true));
        require.AppendLine(BuildPackageScriptText("jquery-ui", "Scripts/ThirdParty/jQuery", "jquery-ui-1.10.2"));
        require.Append(BuildPackageScriptText("jquery-loadmask", "Scripts/ThirdParty/jQuery", "jquery.loadmask"));
        require.AppendLine(BuildPackageScriptText("jsfunctions", "Scripts/Common", "jsfunctions"));
        require.AppendLine(BuildPackageScriptText("logging", "Scripts/TJPackages", "JsLogging"));
        require.AppendLine(BuildPackageScriptText(action, string.Format("Scripts/AMD/Views/{0}", controller), action));
        require.AppendLine("    ]");
        require.AppendLine("};");
        require.AppendLine("</script>");
        require.AppendLine("<script src='" + GetAbsolutePath("Scripts/ThirdParty/ESRI/init.js") + "'></script>");
        require.AppendLine("<script>");
        require.AppendLine(javascriptLogging);
        require.AppendFormat("require(['{0}', 'dojo/domReady!'],function({0})", action);
        require.AppendLine("{");
        //require.AppendLine("debugger;");
        require.AppendFormat("    {0}.init();", action);
        require.AppendLine("});");
        require.AppendLine("</script>");

        return new MvcHtmlString(require.ToString());
    }

    /// <summary>
    /// Common format for packages in the dojoConfig
    /// </summary>
    /// <param name="name"></param>
    /// <param name="location"></param>
    /// <param name="main"></param>
    /// <param name="isFirst">Set to true for the first package and the comma will NOT be appended</param>
    /// <param name="isCDN">Set to true if using a CDN location for your javascript</param>
    /// <returns></returns>
    private static string BuildPackageScriptText(string name, string location, string main, bool isFirst = false, bool isCDN = false)
    {
        var sb = new StringBuilder();

        if (!isFirst)
        {
            sb.Append(",");
        }

        sb.Append("{");
        sb.AppendFormat("name: '{0}', location: '{1}', main: '{2}'", name, isCDN ? location : GetAbsolutePath(location), main);
        sb.Append("}");

        return sb.ToString();
    }
    #endregion

    /// <summary>
    /// Convert the path to work in IIS for MVC
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    private static string GetAbsolutePath(string path)
    {
        return VirtualPathUtility.ToAbsolute("~/" + path);
    }

1 个答案:

答案 0 :(得分:3)

我认为您需要重写C#代码才能使用Url.Content()函数:

  

将虚拟(相对)路径转换为应用程序绝对路径。

但是要确保你应该测试它是否能完成子文件夹中应用程序的工作(即MVCTesting)。在你的代码中(例如_layout文件)只需写:

@Url.Content("/Scripts/AMD/core.js")

在localhost上,输出应该类似于/Scripts/AMD/core.js,但在IIS中它应该是/MVCTesting/Scripts/AMD/core.js。如果是这种情况,请告诉我。