欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

(9)ASP.NET Core 中的MVC路由(二)

程序员文章站 2022-03-20 08:29:44
1.URL生成 MVC应用程序可以使用路由的URL生成功能,生成指向操作(Action)的URL链接。 IUrlHelper 接口用于生成URL,是MVC与路由之间的基础部分。在控制器、视图和视图组件中,可通过Url属性找到IUrlHelper的实例。在此示例中,将通过Controller.Url属 ......

 1.url生成

mvc应用程序可以使用路由的url生成功能,生成指向操作(action)的url链接。 iurlhelper 接口用于生成url,是mvc与路由之间的基础部分。在控制器、视图和视图组件中,可通过url属性找到iurlhelper的实例。在此示例中,将通过controller.url属性使用iurlhelper接口来生成指向另一项操作的url。

public class homecontroller : controller
{
    public iactionresult index()
    {
        var url1= url.action("privacy");//url:home/privacy
        var url2 = url.action("error");//url:home/error
        var url3 = url.action("article");//url:blog/article
        var msg = $"url1: {url1}";
        msg += $"\r\nurl2: {url2}";
        msg += $"\r\nurl3: {url3}";
        return content(msg);
    }
    [httpget("custom/url/to/privacy")]//定义一个路由模版
    public iactionresult privacy()
    {
        return view();
    }
    public iactionresult error(string code)
    {
        return view(new errorviewmodel { requestid = activity.current?.id ?? httpcontext.traceidentifier });
    }
}

响应结果:

(9)ASP.NET Core 中的MVC路由(二)

如果url.action方法都只设置action名称,那么iurlhelper接口会获取通过指向当前所在控制器里存在的action操作,然后生成url。如果当前控制器里action操作自定义路由模版,则会生成对应路由模版url。如果action不存在当前控制器里,则会生成空字符串的url。

2.url生成方式

2.1根据操作名称生成url

url.action (iurlhelper. action) 可以通过指定控制器(controller)名称和操作(action)名称来生成要链接的内容。而重载方法里还包含添加路由值对象,比如url.action("home", "index", new { id = 17 }),此处路由值对象就是new { id = 17 }(路由值对象通常是匿名类型的对象)。下面我们通过示例来看看:

public class homecontroller : controller
{
    public iactionresult index(int id)
    {
        var url = url.action("index", "home", new { id = 17, color = "red", sex = "m" });
        return view();
    }
}

通过debug查看生成url:

 (9)ASP.NET Core 中的MVC路由(二)

2.2根据路由生成url

上面的代码演示了如何通过传入控制器和操作名称来生成url。iurlhelper还提供 url.routeurl系列的方法。这些方法类似于url.action,但它们不会将action和controller的当前值复制到路由值。最常见的用法是指定一个路由名称,以使用特定路由来生成url,通常不指定控制器或操作名称。

public class homecontroller : controller
{
    public iactionresult index(int id)
    {
        var url = url.routeurl("privacy_name");
        return view();
    }
    [httpget("custom/url/to/privacy",name = "privacy_name")]//定义一个路由模版
    public iactionresult privacy()
    {
        return view();
    }
}

通过debug查看生成url:

(9)ASP.NET Core 中的MVC路由(二)

2.3在html中生成url

ihtmlhelper提供htmlhelper方法html.beginform和html.actionlink,可分别生成<form>和 <a>元素。这些方法使用url.action方法来生成url,并且采用相似的参数。htmlhelper的配套url.routeurl为html.beginrouteform和html.routelink,两者具有相似的功能。

@using (html.beginform("article", "blog", formmethod.get, new { name = "nform", id = "idform" })){}
@html.actionlink("article", "article", "blog")

通过浏览器工具查看生成html:

(9)ASP.NET Core 中的MVC路由(二)

2.4在操作结果中生成url

以上示例展示了如何在控制器中使用iurlhelper。不过,控制器中最常见的用法是将url生成为操作结果的一部分。controllerbase和controller基类为操作结果提供简便的方法来引用另一项操作。一种典型用法是在接受用户输入后进行重定向。

public iactionresult edit(int id, customer customer)
{
    if (modelstate.isvalid)
    {
        // update db with new details.
        return redirecttoaction("index");
    }
    return view(customer);
}

3.区域(area)

区域是asp.net功能,它提供了一种将asp.net core web应用程序划分为更小的功能组的方法,每个功能组都有自己的一组razor pages、控制器(controllers)、视图(views)和模型(models)。区域实际上是应用程序内的结构。在asp.net core web项目中,pages、模型、控制器和视图等逻辑组件保存在不同的文件夹中。asp.net core运行时使用命名约定来创建这些组件之间的关系。对于大型应用程序,将应用程序区分为独立的高级功能区域可能更有利。例如,具有多个业务单位(如结账、计费、搜索等)的电子商务应用程序。每个单位都有自己的区域,以包含视图、控制器、razor pages和模型。下面的示例我们根据采购(purchase)和销售(sale)订单两个业务场景在mvc中配置使用默认传统路由和区域路由:

public class startup
{  
    public void configure(iapplicationbuilder app)
    {
        app.usemvc(routes =>
        {
            routes.maparearoute(
                name: "myareapurchase",
                areaname: "purchase",
                template: "purchase/{controller}/{action}/{id?}");
            routes.maparearoute(
                name: "myareasale",
                areaname: "sale",
                template: "sale/{controller}/{action}/{id?}");
            routes.maproute(
                name: "default",
                template: "{controller=home}/{action=index}/{id?}");
            //等价于
            //routes.maparearoute("purorder_route", "purchase",
            //"purchase/{controller}/{action}/{id?}");
            //routes.maparearoute("saleorder_route", "sale",
            //"sale/{controller}/{action}/{id?}");
            //routes.maproute("default", "{controller=home}/{action=index}/{id?}");
        });
    }
}

在上面的示例中,路由值将与以下操作匹配:

[area("purchase")]
public class purordercontroller : controller
{
    public iactionresult index()
    {
        return view();
    }
}
[area("sale")]
public class saleordercontroller : controller
{
    public iactionresult index()
    {
        return view();
    }
}

在每个控制器加入areaattribute属性是表示该控制器是某个区域的一部分,比方说,purordercontroller控制器位于purchase区域中,saleordercontroller控制器位于sale区域中。 而没有 [area] 属性的控制器不是任何区域的成员,在路由提供area路由值时不匹配时,打开对应控制器下的视图时将无法打开。在上面的示例中,只有所列出purordercontroller、saleordercontroller控制器下视图index的路由值 { area = purchase, controller = purorder, action = index } 、{ area = sale, controller = saleorder, action = index }匹配才能打开对应链接。

(9)ASP.NET Core 中的MVC路由(二)

(9)ASP.NET Core 中的MVC路由(二)

4.实现iactionconstraint的路由约束

实现iactionconstraint约束最简单的方法是创建派生自system.attribute的类,并将其置于操作(action)和控制器(controller)上。 mvc将自动发现任何应用为属性的iactionconstraint属性,便对应用程序模型应用程序进行约束。在下面的示例中,对路由数据中的国家/地区选择操作进行约束。

public class countryspecificattribute : attribute, iactionconstraint
{
    private readonly string _countrycode;
    public countryspecificattribute(string countrycode)
    {
        _countrycode = countrycode;
    }
    public int order
    {
        get
        {
            return 0;
        }
    }
    public bool accept(actionconstraintcontext context)
    {
        string routedatavalue = context.routecontext.routedata.values["id"] == null ? "" : context.routecontext.routedata.values["id"].tostring();
        return string.equals(
            routedatavalue,
            _countrycode,
            stringcomparison.ordinalignorecase);
    }
}
public class homecontroller : controller
{
    [countryspecific("en-us")]
    public iactionresult index(string id)
    {
        return view();
    }
}

根据官网解释iactionconstraint.order是顺序约束意思,比如homecontroller 控制器上有[countryspecific("en-us")]和[httpget](或者其他自定义属性约束)属性约束,数值较低的属性约束先运行。响应结果通过下面表格进行分析:

route url

result

[service_name]/home/index/en-us

200

[service_name]/home/index/zh-cn

404

通过以上的表格可以知道,在此例中,当index传入路由值(en-us)匹配时,accept方法返回true以表示该操作是匹配项,然后可以打开连接,反之传入值(zh-cn)不匹配,则404。

 

参考文献:
在 asp.net core 中路由到控制器操作