• ASP.NET Core的路由如何生成URL?
  • 发布于 1个月前
  • 54 热度
    0 评论
ASP.NET Core 应用程序链接都是根据应用程序中定义的路由来创建的,即使路由更新了,链接地址也会跟着更新,从而避免手动更新所有的链接。ASP.NET Core 路由使用下面的帮助标签生成action方法的链接。
1 asp-controller
2 asp-action

一.根据默认路由生成链接
应用程序是如何根据定义的路由创建链接的呢?让我们创建一个ASP.NET Core MVC应用程序,命名为AspNetCore.RouteLinks 

应用程序创建完成之后,你能看到Program类中有一个默认的路由,路由代码如下:
app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");
接下来我们进入HomeController的Index视图,添加下面代码:
<a asp-controller="Home" asp-action="Check">Outgoing URL</a>
运行应用程序,在浏览器中查看生成的HTML格式,我们会发现生成了如下代码:
<a href="/Home/Check">Outgoing URL</a>
如下图所示:                   

我们在超链接标签上使用了asp-controller和asp-action帮助标签(asp-controller="Home" asp-action="Check" ) 生成链接,这个帮助标签告诉dotnet为该标签创建一个href属性,并且该属性值连接到HomeController的Check方法。
dotnet会使用应用程序给定的路由为check方法创建一个完整的url链接,应用程序已经包含默认路由,因此根据默认路由能够生成url,如果我们有多个路由,dotnet将依次匹配每个路由并且使用匹配成功的路由创建url,涉及到路由匹配的问题,我们后面会涉及到。
下面代码指向Customer控制器的Check方法,下面代码将工作:
<a asp-controller="Customer" asp-action="Check">Check action of Customer Controller</a>
在这种情况下,生成如下链接:
<a href="/Customer/Check">Check action of Customer Controller</a>

二 智能化生成链接
进入Home控制器的Check方法,创建一个指向Index方法的链接
<a asp-action="Index">Go to Index</a>
在这种情况下,你会发现在HTML中生成的地址仅仅包含/ 而不是Home/Index,如下所示:
<a href="/">Go to Index</a>

这是因为在应用程序中定义的路由针对controller和action提供了默认值,默认的controller是Home,默认的action是Index,这和asp-controller和asp-action帮助标签功能是相等的,因此ASP.NET Core没有给Href属性添加Controller和Action。


三 根据Attribute路由生成链接
使用Attribute路由生成链接,添加AdminController在应用程序中,添加下面代码:
using Microsoft.AspNetCore.Mvc;
namespace RouteLinks.Controllers
{
    [Route("News/[controller]/USA/[action]/{id?}")]
    public class AdminController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }
    }
}
在AdminController上添加一个路由,使用attribute 路由生成一个链接。
在Home控制器的Index方法添加一个超链接标签,设置asp-controller=Admin,asp-action=Index 代码如下:
<a asp-controller="Admin" asp-action="Index">Index Action of Admin Controller</a>
下面是Attribute 路由生成的链接:
<a href="/News/Admin/USA/Index">Index Action of Admin Controller</a>

四. 当出现多个路由时生成外部链接
当应用程序中出现多个路由时,路由中间件会按照他们在Program类中定义的顺序来处理并且生成对外的链接,基于下面3个规则尝试与每个路由做匹配:
(1) 每个URL段必须提供一个值
(2) 对于仅限默认值的变量,我们必须要么不提供值,要么提供与默认值匹配的值
(3) 变量段的值应满足路线约束
URL中如果没有使用默认路由变量,但是路由本身提供了默认值,例子:在如下路由中,controller变量有默认值,因此路由中间件做匹配,有了默认值之后,我们不给该变量提供默认值时,该变量使用USA作为默认值
app.MapControllerRoute(
    name: "defaultonly",
    pattern: "{controller}/{action}",
    defaults: new { controller = "USA" });
假如你应用程序中有2个路由
app.MapControllerRoute(
    name: "stock",
    pattern: "Stock/{action}",
    defaults: new { controller = "Home" });
app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");
在Home控制器的Index视图中添加下面代码:
<a asp-action="Index">Link1</a>
<a asp-controller="Product">Link2</a>
生成下面代码:
<a href="/Stock/Index">Link1</a>
<a href="/Product">Link2</a>

第一个链接生成url使用了stock路由,第二个链接生成url使用了default,在第一个链接<a asp-action="Index">Link1</a>中,我们没有给controller 提供值,因为它使用了默认值,因此这里满足第二条规则,我们也可以使用<a asp-controller="Home" asp-action="Index">产生相同的链接,这里我们给controller参数提供了Home的值,在这种情况下第二条规则被匹配成功。


五. asp-route-{value}
到目前为止,您已经看到了如何使用控制器和方法创建链接,如果我们想要给其它段变量传递值,如id?,我们可以使用asp-route-{value}帮助标签,将{value}替换变量段的名称,如id,让我们创建一个链接,并传递一个Id的值。

创建一个名字为ProductController控制器,并添加一个Index方法:
using Microsoft.AspNetCore.Mvc;
namespace RouteLinks.Controllers
{
    public class ProductController : Controller
    {
        public string Index(int id)
        {
            return "Id Value is: " + id;
        }
    }
}
我们从Home控制器的Index视图链接到Product控制器的Index方法,我们给Id段传递一个值,使用asp-route-{value} 帮助标签添加下面链接在Home控制器的Index视图中:
<a asp-controller="Product" asp-action="Index" asp-route-id="100">Pass 100 to the id segment</a>
现在运行应用程序并且检查html中生成的链接:
<a href="/Product/Index/100">Pass 100 to the id segment</a>
点击链接,将会跳转到Product控制器的Index方法,我们将显示Id段的值,这个段的值是100,使用asp-route-{value}帮助标签来设置该值    


六 根据指定路由生成链接
我们还可以使用路由名字生成链接,这时需要我们给asp-route标签指定一个具体的路由名称,代码如下:
app.MapControllerRoute(
    name: "sales",
    pattern: "sales/{controller=Home}/{action=Index}");
我们现在使用路由来创建一个链接,使用asp-route帮助标签,asp-route="sales",sales是路由的名称。

在View中添加下面代码:
<a asp-route="sales">Sales</a>
将会生成如下地址:
<a href="/sales">Sales</a> 
我们除了使用asp-controller和asp-action帮助标签之外,还可以使用asp-route标签。
这意味着路由对Controller和Action有默认值。
七 Url.Action
我们还可以使用Url.Action()方法给action方法生成url,该方法是是根据应用程序中指定的路由来生成的,在HomeController的Index方法添加如下代码:
<p>@Url.Action("List", "Product", new { id = 10 })</p>
生成的url
/Product/List/10
 Url.Action() 方法使用下面参数:
  (1) Controller名称
  (2) Action名称
  (3) asp-route-{value}
也可以在action方法中使用Url.Action() ,代码如下:
string url = Url.Action("Index", "Home", new { id = 100 });
这里第一个参数是Action名称,第二个参数是Controller名称,第三个参数是asp-route-{value}

八 URL 片段(#)
使用#表示一个url片段,#是可选的并且位于url最后,#代表网页中的一个位置,例如:在锚点标签如下,url片段的名称为"Printing",因此当我们点击这个锚点,浏览器会搜索id为"Printing"的html标签,并且会滚动到这个标签。
<a href="/Product/List#Printing">Printing</a>
我们可以使用asp-fragment="fragment-name" 帮助标签创建URL片段
<a asp-controller="Product" asp-action="List" asp-fragment="Printing">
    URL Fragment
</a>
九. 在网页尾部添加斜杠(/)
RouteOption可以设置URL生成以至于在URL末尾能包含斜杠(/),进入Program.cs类并且添加代码:
builder.Services.Configure<RouteOptions>(options =>
{
    options.AppendTrailingSlash = true;
});
将会生成如下url
https://localhost:7248/Stock/Index/
https://localhost:7248/Product/
https://localhost:7248/Product/Index/100/
十.小写URL
为了使URL变得更优雅,我们可以使用如下代码将其设置成小写的形式:
builder.Services.Configure<RouteOptions>(options =>
{
   // 堆代码 duidaima.com
    options.LowercaseUrls = true;
});
路由中间件会将url设置为小写形式
例如:check 方法的url http://localhost:58470/home/check/

总结
这节我们主要学习了在ASP.NET Core路由如何生成URL
用户评论