为了简单地回答您的问题,是的,我考虑了您列出的“硬编码”两个示例。第二,@Url.Action 没有硬编码。它隐含的特异性较低。如果您更改了项目的根目录,第二个仍然可以工作,而第一个会像@Peter J 提到的那样中断。另外,我想如果您使用区域并更改了区域名称,第二个会工作,而第一个会打破。
不过,为了更有帮助,我使用了第三种方法。一个月前我正好有你的问题,感谢没有静态控制器 URL(魔术字符串)的 ASP.NET MVC AJAX 调用,我有一个非常适合我的过程。
索引.cshtml
<input data-action='@Url.Action(Mvc.AutoComplete.PostalCode())' type='text' name='postalCode' class='autoComplete'><input>
<input data-action='@Url.Action(Mvc.AutoComplete.ProductCategory())' type='text' name='productCategory' class='autoComplete'><input>
main.js
$('input.autoComplete').each(function () {
var el = $(this);
el.autocomplete({source: el.data('action')});
});
瞧!通过 T4MVC 和 HTML5 数据属性进行编译时检查和明确的职责分离。控制器定义是从使用它的小部件中读取的。非常适合可能在页面上多次出现的部分视图。
我强烈推荐使用 T4MVC,即“Mvc”。您在示例视图中看到的语法。如果您试图避免“硬编码”,那将是尽可能动态的。我使用 T4MVC ( http://t4mvc.codeplex.com/ ),所以我可以避免“魔术字符串”在我的视图中引用控制器和操作。T4MVC 并不完美,但它是一个很大的改进。在隐藏的 T4MVC 文件中,仍然有硬编码的值,但您永远不会看到它们,它们是从您的控制器自动生成的,并在编译时进行检查。
此外,正如@Valamas 在这里所建议的那样,然后我使用 HTML 元素上的数据属性将这些 URL 从我的视图传递到 javascript。
当我的页面上有 AJAX 调用时,我特别使用这种数据属性方法。一个页面可能很容易有 10 个 URL 依赖项,并且很难通过可能没有完全覆盖条件功能的用户测试来判断链接何时被破坏。但是,万岁!当链接不存在时,T4MVC 会引发编译时错误,并且如果您的代码是用 init 中的所有数据属性检查来组织的,那么当相应的数据属性丢失时,javascript 会引发加载时错误(而不是运行时错误)你会得到未定义的变量)。这提供了更早/更容易检测链接缺陷,即使您没有对 javascript 进行单元测试(我也没有)。
我通常在每个页面上都有一个标准标题,其中包含当前全局有用的信息(例如,UserId)作为 BODY 元素上的数据属性,或者在具有众所周知的 ID 的 display:none SPAN 上。
然后,我通常会在靠近我的 javascript 代码(或每个需要它的 javascript 文件)顶部的单个位置从属性加载所有数据。
这有什么好处?现在,您可以在一个地方查看以确保将所需的所有嵌入数据参数提供给您的 javascript。您的 javascript 不会引用未定义的变量,因此如果您使用 javascript IDE,您将不会收到错误错误。查看您的 javascript 的开发人员不会想尽办法在其他 javascript 文件中找到神秘变量的声明;当他们不是 ASP.NET MVC 开发人员时尤其麻烦。在这一点上,如果您有单独的语言团队,则实施职责会更加清晰(您的 javascript 开发人员在更改命名约定时不会来编辑您的视图,反之亦然)。此外,变量是在客户端页面生命周期中的一个众所周知的时间点定义的,这对于调试 javascript 是一个很大的好处。并且您的视图不包含遍布整个页面的 javascript,其中一个小的中间页面 HTML 缺陷可能会意外地导致完整的 javascript 失败。
此外,如示例中所示,这是获取可能在页面上多次出现的部分视图的唯一方法。您可以清楚地将嵌入数据与使用它的单个 HTML 小部件相关联。如果您将 javascript 直接插入到视图中,您将错误地重新定义变量。
好处的清单不胜枚举,但基本上归结为责任分离。其他一切都由此而来。