有没有办法有一个路线preFIX与一个可选的参数开始? [英] Is there a way to have a RoutePrefix that starts with an optional parameter?

查看:172
本文介绍了有没有办法有一个路线preFIX与一个可选的参数开始?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想达到这些URL的自行车控制器:

  /自行车//(美国默认路径)
/ CA /自行车//(加拿大路径)

实现这一的一种方法是使用多个路由每行动属性​​:

  [路线(自行车)]
[路线({}国家/自行车)]
公众的ActionResult指数()

要保持干燥我倒是preFER使用路由preFIX,但多个路线prefixes是不允许的:

  [路线preFIX(自行车)]
[途径preFIX({}国家/自行车)] //< - 错误:重复的'路线preFIX'属性
公共类BikesController:BaseController    [路线()]
    公众的ActionResult指数()

我只使用这个路线preFIX尝试:

  [路线preFIX({}国家/自行车)]
公共类BikesController:BaseController

结果:/ CA /自行车的工作,/自行车404

我试图使国家可选:

  [路线preFIX({国家?} /自行车)]
公共类BikesController:BaseController

同样的结果:/ CA /自行车的工作,/自行车404

我试着给国家一个默认值:

  [路线preFIX({=国美} /自行车)]
公共类BikesController:BaseController

同样的结果:/ CA /自行车的工作,/自行车404

有另一种方式使用属性来实现我的目标路由?
(是的,我知道我可以通过注册在RouteConfig.cs路线做这个东西,但是这不是我要找的东西在这里)。

我使用Microsoft.AspNet.Mvc 5.2.2。

FYI:这些都是简化的例子 - 实际code先后为国家{}值的IRouteConstraint,如:

  [路线({国家:国家code} /自行车)]


解决方案

你是正确的,你不能有多个路由prefixes,这意味着解决这个特定用例不会是直线前进。关于我能想到的最好的方式来实现你想要修改到项目中少量什么是子类控制器。例如:

  [路线preFIX(自行车)]
公共类BikeController:控制器
{
    ...
}[途径preFIX({}国家/自行车)]
公共类CountryBikeController:BikeController
{
}

您的子类控制器将继承所有从 BikeController 的行动,这样你就不会需要重新定义什么,本身。然而,当涉及到生成URL,让他们去正确的地方,你要么需要明确的控制器名称:

  @ Url.Action(指数,CountryBike,新{国家=US}

或者,如果你使用的命名路由,你就必须重写你的行为在你的子类控制器,以便你可以申请新的航线名称:

  [路线(NAME =CountryBikeIndex)]
公众覆盖的ActionResult指数()
{
    base.Index();
}

另外,要记住,这用路径prefixes参数时,所有在该控制器你的行为应该采取的参数:

 公众的ActionResult指数(字符串国家=US)
{
    ...

I want to reach the Bikes controller with these URL's:

/bikes     // (default path for US)
/ca/bikes  // (path for Canada)

One way of achieving that is using multiple Route Attributes per Action:

[Route("bikes")]
[Route("{country}/bikes")]
public ActionResult Index()

To keep it DRY I'd prefer to use a RoutePrefix, but multiple Route Prefixes are not allowed:

[RoutePrefix("bikes")]
[RoutePrefix("{country}/bikes")] // <-- Error: Duplicate 'RoutePrefix' attribute    
public class BikesController : BaseController

    [Route("")]
    public ActionResult Index()

I've tried using just this Route Prefix:

[RoutePrefix("{country}/bikes")]
public class BikesController : BaseController

Result: /ca/bikes works, /bikes 404s.

I've tried making country optional:

[RoutePrefix("{country?}/bikes")]
public class BikesController : BaseController

Same result: /ca/bikes works, /bikes 404s.

I've tried giving country a default value:

[RoutePrefix("{country=us}/bikes")]
public class BikesController : BaseController

Same result: /ca/bikes works, /bikes 404s.

Is there another way to achieve my objective using Attribute Routing? (And yes, I know I can do this stuff by registering routes in RouteConfig.cs, but that's what not I'm looking for here).

I'm using Microsoft.AspNet.Mvc 5.2.2.

FYI: these are simplified examples - the actual code has an IRouteConstraint for the {country} values, like:

[Route("{country:countrycode}/bikes")]

解决方案

You're correct that you can't have multiple route prefixes, which means solving this particular use case is not going to be straight forward. About the best way I can think of to achieve what you want with the minimal amount of modifications to your project is to subclass your controller. For example:

[RoutePrefix("bikes")]
public class BikeController : Controller
{
    ...
}

[RoutePrefix("{country}/bikes")]
public class CountryBikeController : BikeController
{
}

You subclassed controller will inherit all the actions from BikeController, so you don't need to redefine anything, per se. However, when it comes to generating URLs and getting them to go to the right place, you'll either need to be explicit with the controller name:

@Url.Action("Index", "CountryBike", new { country = "us" }

Or, if you're using named routes, you'll have to override your actions in your subclassed controller so you can apply new route names:

[Route("", Name = "CountryBikeIndex")]
public override ActionResult Index()
{
    base.Index();
}

Also, bear in mind, that when using parameters in route prefixes, all of your actions in that controller should take the parameter:

public ActionResult Index(string country = "us")
{
    ...

这篇关于有没有办法有一个路线preFIX与一个可选的参数开始?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆