问题:ASP.NET无法识别外部脚本

时间:2011-04-04 09:12:49

标签: c# javascript jquery asp.net-mvc-3

我有一个简单但非常讨厌的问题。我有一个ASP.NET MVC3应用程序与Razor作为视图引擎。

如果我将整个代码放在_layout页面中,我从部分视图调用了两个脚本。如果我将脚本放在外部文件中并引用它们,它们就不起作用。怎么会这样?我已经检查过基本问题,例如文件位置和脚本标记的语法。

以下是JavaScript代码:

$(document).ready(function () {
$('#Year').change(function () {
    var selectedYear = $(this).val();
    if (selectedYear != null && selectedYear != '') {
        $.getJSON('@Url.Action("Months", "Home")', { year: selectedYear }, function (months) {
            var monthsSelect = $('#Month');
            monthsSelect.empty();
            $.each(months, function (index, month) {
                monthsSelect.append($('<option/>', {
                    value: month.value,
                    text: month.text
                }));
            });
        });
    }
}).change();

});

这里是_Layout文件中的引用:

<script src="../../Scripts/CascadeDropDownList.js" type="text/javascript"></script>

这是将Json结果返回给视图的操作方法:

public ActionResult Months(int year)
    {
        if (year == DateTime.Now.Year)
        {
            return Json(
                Enumerable.Range(1, (DateTime.Now.Month -1)).Select(m => new 
                {
                    value = m,
                    text = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(m)
                }),
                JsonRequestBehavior.AllowGet
            );
        }
        return Json(
            Enumerable.Range(1, 12).Select(m => new 
            {
                value = m,
                text = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(m) 
            }),
            JsonRequestBehavior.AllowGet
        );
    }

堆栈:

[ArgumentException: Illegal characters in path.]
   System.IO.Path.CheckInvalidPathChars(String path) +126
   System.IO.Path.Combine(String path1, String path2) +38
   System.Web.Configuration.UserMapPath.GetPhysicalPathForPath(String path, VirtualDirectoryMapping mapping) +114
   System.Web.Configuration.UserMapPath.GetPathConfigFilename(String siteID, VirtualPath path, String&amp; directory, String&amp; baseName) +82
   System.Web.Configuration.UserMapPath.MapPath(String siteID, String path) +58
   System.Web.Hosting.HostingEnvironment.MapPathActual(VirtualPath virtualPath, Boolean permitNull) +301
   System.Web.Hosting.HostingEnvironment.MapPathInternal(VirtualPath virtualPath, Boolean permitNull) +51
   System.Web.CachedPathData.GetPhysicalPath(VirtualPath virtualPath) +39
   System.Web.CachedPathData.GetConfigPathData(String configPath) +704
   System.Web.CachedPathData.GetVirtualPathData(VirtualPath virtualPath, Boolean permitPathsOutsideApp) +110
   System.Web.HttpContext.GetFilePathData() +36
   System.Web.HttpContext.GetConfigurationPathData() +26
   System.Web.Configuration.RuntimeConfig.GetConfig(HttpContext context) +43
   System.Web.Configuration.CustomErrorsSection.GetSettings(HttpContext context, Boolean canThrow) +41
   System.Web.HttpResponse.ReportRuntimeError(Exception e, Boolean canThrow, Boolean localExecute) +101
   System.Web.HttpRuntime.FinishRequest(HttpWorkerRequest wr, HttpContext context, Exception e) +397
</pre></code>

提前致谢

2 个答案:

答案 0 :(得分:1)

永远不要硬编码这样的网址:

<script src="../../Scripts/CascadeDropDownList.js" type="text/javascript"></script>

处理网址时始终使用网址助手:

<script src="@Url.Content("~/Scripts/CascadeDropDownList.js")" type="text/javascript"></script>

还要确保您的控制器操作不会抛出异常,并且由于JSON部分确保它允许GET请求:

public ActionResult Months(int year) 
{
    var someModel = ...
    return Json(someModel, JsonRequestBehavior.AllowGet);
}

最后确保从此操作返回的模型是一个集合,并且此集合的每个元素都拥有textvalue属性(区分大小写)。

您还尝试使用脚本末尾的.change()方法调用做什么?如果要在加载页面时填充此下拉列表,我强烈建议您在服务器端执行此操作(在相应的控制器操作中呈现此视图)。

答案 1 :(得分:1)

问题是剃刀解析器没有处理JS文件,因此这个代码在客户端上被渲染,正好是这个

$(document).ready(function () {
$('#Year').change(function () {
    var selectedYear = $(this).val();
    if (selectedYear != null && selectedYear != '') {
        $.getJSON('@Url.Action("Months", "Home")', { year: selectedYear }, function (months) {
            var monthsSelect = $('#Month');
            monthsSelect.empty();
            $.each(months, function (index, month) {
                monthsSelect.append($('<option/>', {
                    value: month.value,
                    text: month.text
                }));
            });
        });
    }
}).change();

请注意,请求网址与客户端完全相同

  

@ Url.Action(“Months”,“Home”)

它没有转换为真实的URL,因为razor解析器不处理JS文件。或者,事实上任何其他解析器。这就是为什么外部文件无法正常工作的原因。如果你把它放在剃刀视图中,@ Url.Action由razor处理,它在客户端产生有效的链接