8

我正在查看以下 jQuery 调用:

$.get('/Home/GetResult', null, function (data) {

    alert(data);

});

与以下相比,我认为这被称为“硬编码”方式:

$.get('@Url.Action("GetResult", "Home")', function (data) { 

    alert(data);

});

我认为这被称为非硬编码方式。

有人可以向我解释一下这是怎么回事吗?在我看来,这两种方式都是同样硬编码的调用方式,因为你在两者中都有明确的控制器和方法名称。

有谁知道为什么一个被称为硬编码而另一个不是。一个更好吗?

4

5 回答 5

5

如果我们对 URL 进行硬编码,那么我们将失去以后更改路由方案的能力。所以总是使用 URL Helper 方法。如果您使用 URL 助手,Helper 方法将负责更改,您无需在 100 处进行更改。此外,当从主页和内页调用相同的方法时,您不必担心我必须添加多少 ../ 作为前缀

查看达林的这些答案

https://stackoverflow.com/a/7492024/40521

https://stackoverflow.com/a/6454041/40521

于 2012-07-24T21:43:04.880 回答
4

“/Home/GetResult”被认为是“硬编码”,因为开发人员直接在代码中输入了配置值,以后更难更改。

专门硬编码 URL 值更糟糕,因为如果这个视图(和相关的控制器操作)被移动到应用程序中的另一个“区域”,“/Home/GetResult”将会中断。@Url.Action 方法更好,因为不会。

于 2012-07-24T21:43:36.953 回答
2

我喜欢彼得 J 的回答。此外

您应该将 URL 作为 href 的一部分或作为 html 元素的属性。

E.g <a data-getresult="@Url.Action("GetResult", "Home")">click</a>

进而

var clickAction = $(this).attr('data-getresult');
$.get(clickAction, null, function (data) {

    alert(data);

});

将上述内容包装在一个函数中,并通过属性名称将其链接到单击事件。

于 2012-07-24T21:45:35.863 回答
1

为了简单地回答您的问题,是的,我考虑了您列出的“硬编码”两个示例。第二,@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 直接插入到视图中,您将错误地重新定义变量。

好处的清单不胜枚举,但基本上归结为责任分离。其他一切都由此而来。

于 2012-07-25T03:42:55.713 回答
0

大多数时候,他们会实现同样的目标。

本质上,如果您有一个没有区域的简单 MVC 站点,并且您使用的是默认路由定义,您将不会注意到太大的变化。但是如果你在你的应用中自定义路由定义或者使用区域,你很可能会遇到问题。在可能的情况下,建议您使用软编码方法。如果您需要将 URL 嵌入到 JavaScript 文件中,就会出现问题。但是在这种情况下,它通常表明您的实现存在问题,并且您的 JS 文件中的代码应该接受它将用作参数的 URL,而不是将其嵌入到您的外部 JS 文件中。

于 2012-07-24T21:50:31.617 回答