【问题标题】:How to create consistent URLs with MVC .NET routing?如何使用 MVC .NET 路由创建一致的 URL?
【发布时间】:2021-07-16 20:34:30
【问题描述】:

我在 .NET Framework 4.8 中运行 ASP.Net MVC 5。由于生成的 URL 不一致,我不断收到 404 错误。例如,在包含在每个页面顶部的 _PageNav.chstml 部分中,我将以下内容带回主页:@Url.Action("Index", new { controller = "Home" })。在导航栏中,这将解析为 <a class="navbar-brand" href="/" /> 并正常运行。

当我在同一页面上使用相同的 @Url.Action("Index", new { controller = "Home" }),但稍后在按钮上使用时,它会解析为:<a id="doneButton" class="btn btn-secondary px-4" href="https://localhost:44337/smrt/">Done</a>

由于这种不一致,我经常遇到这样的问题,即对控制器的 AJAX JavaScript 引用最终会丢失控制器引用,例如 /create 导致 https://localhost:44337/create 而不是 https://localhost:44337/home/create/home/create 导致 https://localhost:44337/home/home/create 而不是https://localhost:44337/home/create

由于安全限制,我也有一些限制;例如,我不能在页面本身上有任何 JavaScript,所以我不能在我的 .cshtml 文件中编写会生成 JavaScript 的剃须刀代码。我只能使用页面源文件中引用的 JavaScript。

【问题讨论】:

    标签: javascript c# ajax asp.net-mvc url.action


    【解决方案1】:

    @Url.Action("Index", "Home") 应该足以完成这项工作,但我注意到有时在更改级别时自定义路由正在发挥作用的一些问题。 Url.Action 例程不会呈现完全限定的 url,有时我发现当一个控制器的视图对另一个文件夹的视图进行 AJAX 调用时,我必须附加“../”才能导航到不同的控制器结构。此外,默认 URL 结构可能会抛出相对 URL 调用,因为默认实现是在 URL 结构中隐藏 /Index。所以网址:

    • 本地主机/站点(默认主页/索引)
    • localhost/site/other(默认索引)

    在不同的文件夹结构中看到两个视图,并且 URL 导航可能会被抛出。

    这就是我的经验,为什么您可能会看到您遇到的一些问题。

    【讨论】:

    • 这是一些很好的洞察 MVC .NET URL 行为。如何将其应用于创建一致的 URL 以消除问题?
    【解决方案2】:

    需要一些不同的想法,但我能够解决我的问题。现在,我每次都能以我需要的方式获得一致的 URL。

    首先,我使用这篇文章How to Build Absolute Action URLs Using the UrlHelper Class,创建了一个基于UrlHelper类的扩展方法的follwoing类。

    using System.Web.Mvc;
    
    namespace MVCPages.Utilities
    {
        public static class UrlHelperExtenions
        {
            /// <summary>
            /// Generates a fully qualified URL to an action method by using
            /// the specified action name, controller name and route values.
            /// </summary>
            /// <param name="url">The URL helper.</param>
            /// <param name="actionName">The name of the action method.</param>
            /// <param name="controllerName">The name of the controller.</param>
            /// <param name="routeValues">The route values.</param>
            /// <returns>The absolute URL.</returns>        
            public static string AbsoluteAction(
                this UrlHelper url,
                string actionName,
                string controllerName,
                object routeValues = null
            )
            {
                var httpContext = url.RequestContext.HttpContext;
                string scheme = httpContext.Request.Url.Scheme;
    
                return url.Action(
                    actionName,
                    controllerName,
                    routeValues,
                    scheme
                );
            }
        }
    }
    

    无论网站部署在哪里,这种新方法都会动态地为我提供网站的根目录。

    然后我在需要 URL 一致性的视图中调用新方法扩展,并使用 ViewBag 将绝对根 URL 传递给视图。

    public ActionResult Index()
    {
       string rootUrl = Url.AbsoluteAction("Index", "Smrt");
       ViewBag.RootUrl = rootUrl;
    }
    
    

    由于不允许我使用 Razor 创建 JavaScript,接下来我使用 Razor 创建一个隐藏的 HTML div 标签,其中包含根 URL,&lt;div id="rootUrl"&gt;https://rooturl.com/&lt;/div&gt;

    现在,在 JavaScript 中,我使用 DOM 从 HTML 标记中检索 URL;然后使用我的 ajax 调用的广告为 AJAX 调用创建一个完整的 URL。

    window.onload = function () { 
       var rootUrl = document.getElementById("rootUrl").innerHTML;
       var ajaxUrl = rootUrl + ajaxCall;
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-26
      相关资源
      最近更新 更多