【问题标题】:Alternative for url parameter in ajax when publish发布时 ajax 中 url 参数的替代方案
【发布时间】:2017-09-25 08:19:27
【问题描述】:

我在我的应用程序中使用了一个 WEB API 控制器,并且我正在使用 ajax 来调用该控制器方法。

网址是:

url: "/api/Informations/" + link.attr("data-id")

这在我的本地机器上完美运行。

问题在于我何时发布。

我必须将 URL 更改为:

url: "ProjectNameOnServer/api/Informations/" + link.attr("data-id")

有解决办法吗?因为如果有任何与此相关的问题,我将不得不不断更改 url 以在我的本地计算机上对其进行测试..然后当问题解决..将其更改回它在服务器上工作的版本。

对此有什么想法吗?

更新

api 路由:

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

【问题讨论】:

  • 您可以在配置文件中创建常量,其中开发和实时服务器设置将不同。
  • 你能举个例子吗?
  • 我不知道如何在 asp.net 中进行操作,但像这样:drupal.stackexchange.com/questions/9/…,其中 settings.php 或 config.php 具有所有开发和实时服务器设置。您还可以将此文件添加到忽略(如 gitignore)列表中,以免意外在实时服务器上发送设置。
  • P.S.要回答您的问题 - 大概“api”路线比您的应用程序部署位置低一级?如果是这样,您应该能够使用像url: "api/Informations/" + link.attr("data-id") 这样的相对路径。请注意缺少前导 /。这应该使应用程序自包含,并且不知道它在网络服务器的文件夹层次结构中的部署位置。
  • 当你使用 EF.. 它会使你的控制器模型复数化.. 因此信息.. 另外这不是我的控制器的真实名称.. 只是一个测试用例

标签: ajax asp.net-mvc asp.net-web-api


【解决方案1】:

我不会使用config.Routes.MapHttpRoute() 配置,而是使用属性路由。不幸的是,进行此更改可能很耗时,但它应该可以解决您的问题。 (作为测试,您可以只设置一个带有属性的操作,看看它是否有效。)

步骤 1WebApiConfig.Register 方法中的 config.Routes.MapHttpRoute() 替换为:

config.MapHttpAttributeRoutes();

第 2 步使用以下属性装饰您的 InformationController

[RoutePrefix("api/information")]
public class InformationController: ApiController { ... }

第 3 步使用以下属性装饰您的操作:

[HttpPost, Route("{id:int}", Name = "InformationSingleGet"]
public Information Get([FromBody] int id) { ... }

第 4 步使用 Razor UrlHelper.RouteUrl 方法将您的路由传递到您的 JavaScript:

var infoGetUrl = '@Url.RouteUrl("InformationSingleGet")';

使用RouteUrl 方法的好处是它会为您构建URL,而无需您在不同环境之间进行更改。能够通过名称引用它们使得这很容易找到正确的。

如果您不知道,另一件事是 FromUriFromBody 属性,用于告诉您的方法操作参数的来源。

当然,如果您要在生产代码中使用它,您应该设置一个常量类,在其中将这些路由名称设置在一个地方,并通过对属性的引用来设置它们。您也不应该将变量扔到 JavaScript 窗口对象中,但这是一个不同的讨论。

更新

如果您正在使用这样的路由引擎,对于任何 POST 或 URL 的其他动态尾随部分,您应该使用查询字符串参数而不是 URL 的直接部分。

当您调用Url.RouteUrl 时会发生什么,它会在此时构建整个 URL。因此,当您创建 URL 时,您需要知道作为 URL 一部分的任何动态值是什么。如果它在此页面上(api/information/1/details)会很好,但如果您从列表中选择一个,您不会提前知道这一点。因此,查询字符串参数或正文是要走的路。

为了设置一个动态参数,你可以这样设置:

[Route("{id:int}/details", Name = "InformationDetails")]

然后像这样在你的页面中创建它:

var detailsUrl = '@Url.RouteUrl("InformationDetails", {id = model.Id})';

【讨论】:

  • 对不起,我忘了在问题中包含方法是POST,所以是否应该对步骤 3 进行编辑?
  • 啊,是的。我会改变的。
  • 我刚刚在本地测试过,发布后就可以了!
  • 所以这意味着应用程序知道它托管在 IIS 上的虚拟文件夹中并适当地生成 URL。那就更好了。
  • 等一下..愚蠢的错误..我在错误的页面上.. omg..需要咖啡
【解决方案2】:

在您的母版页或包含在母版页中的 JavaScript 文件中,创建一个变量并在其中设置基本 URL。对于所有 ajax 操作,请在 URL 之前附加此变量。

因此,如果您在 UI 中使用 MVC,则可以在 _layouts.cshtml 中执行以下操作。

<script>
var settings = {};
settings.baseUri = '@Request.ApplicationPath';
</script>

在您的 ajax 调用中,您可以将其更改为:

url: settings.baseUri + "/api/Informations/" + link.attr("data-id")

【讨论】:

    【解决方案3】:

    我在我的 js 文件中使用以下函数来访问 api:

    var isAppFolder = true;//true: when deployed & false: when running locally
    function rootUrl() {
    if (!window.location.origin) {
        window.location.origin = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port : '');
    }
    var url = window.location.origin + "/";
    
    if (isAppFolder != true)
        return url;
    
    var url = url + location.pathname.split('/')[1] + '/';
    if (isAppFolder == true)
        return url;
    
    var url = url + location.pathname.split('/')[2] + '/';
    
    return url;
    }
    

    并像这样访问网址:

    url: rootUrl() +"api/Informations/" + link.attr("data-id")
    

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2012-01-25
      • 1970-01-01
      • 2015-06-13
      • 2013-05-22
      • 1970-01-01
      • 2019-05-01
      • 2010-11-22
      • 1970-01-01
      • 2017-07-15
      相关资源
      最近更新 更多