Как мне отформатировать имена зависимостей для RequireJS в MVC при использовании IIS?
Я следовал за теперь удаленным блогом (см. Весь мой код ниже для того, что я сделал), чтобы создать базовую структуру RequireJS в MVC. Пока в IIS Express все работает как положено. Когда в IIS основной модуль не найден. Единственное различие между ними (IIS и IIS Express) заключается в том, что в путях к карте отображается wwwroot для IIS и фактический путь к файлу, который я разрабатываю для 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 содержит требуемый файл в следующем формате (примечание: по какой-то причине он позволяет мне добавлять.js в имя модуля, но я не уверен в этом).
<script type="text/javascript">
require( [ "/Scripts/AMD/core.js" ], function() {});
</script>
Каким должен быть формат имени зависимости ("/Scripts/AMD/core.js") для правильной загрузки в MVC и с использованием IIS? Мой проект называется 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 ответ
Я думаю, что вам нужно переписать код C#, чтобы использовать Url.Content()
функция:
Преобразует виртуальный (относительный) путь в абсолютный путь приложения.
Но чтобы убедиться, что вы должны проверить, выполняет ли он работу для приложений в подпапке (т.е. MVCTesting
). В вашем коде (например, в файле _layout) просто напишите:
@Url.Content("/Scripts/AMD/core.js")
На localhost вывод должен быть что-то вроде /Scripts/AMD/core.js
, но в IIS это должно быть /MVCTesting/Scripts/AMD/core.js
, Дайте мне знать, если это так.