当我具有多个路由属性时,如何生成特定的操作URL?

时间:2019-01-01 20:43:43

标签: c# .net model-view-controller asp.net-core routes

在我的应用程序中,我有一个定义两个路由的基本控制器类:

// OPControllerBase.cs
[ApiController]
[Route("/[controller]", Order = 1)]
[Route("/inline/[controller]", Order = 2)]
public abstract class OPControllerBase : Controller
{
}

我所有派生的控制器都可以通过/ [controller]或/ inline / [controller]访问。各个动作都用HttpGet / Post装饰,并且可以提供表示该动作的其他路由段。 这是一个派生的控制器示例:

public class ProductController : OPControllerBase
{
    [HttpGet("Edit/{code}")]
    public IActionResult Edit(string code)
    {
       // accessible via both:
       // /Product/Edit/CODE
       // /inline/Product/Edit/CODE
    }
}

在我的_ViewStart.cshtml内部,我基本上决定了布局,具体取决于调用控制器的路径:

// _ViewStart.cshtml
@{
    var path = ViewContext.HttpContext.Request.Path.Value;
    if(path.StartsWith("/inline/"))
    {
        Layout = "_InlineLayout";
    }
    else
    {
        Layout = "_FullLayout";
    }
}

我遇到的问题是,在我的视图内部,我将需要根据控制器的调用方式生成一条路由。如果控制器是通过'/ inline / [controller]'路由调用的,那么我想生成以'/ inline /开头的Urls。另外,我还要选择在某些情况下生成的路由。

当前,每当我生成Url时,它总是使用第一条路线。 如何强制使用第二个?

编辑: 只是为了澄清当我说“生成” URL时,我的意思是使用Url.Action或类似方法。当然,我总是可以明确地编写网址:

var productCode = "TEST";
var fullRoute = "/Product/Edit/" + productCode 
var inlineRoute = "/inline/Product/Edit/" + productCode 

...但这不是我想要做的。我想要的是这样的东西(只是一个当然不起作用的例子):

var productCode = "TEST";
var fullRoute = Url.Action("Edit", "Product", new { code=productCode , inline = false})
var inlineRoute = Url.Action("Edit", "Product", new { code=productCode , inline = true})

1 个答案:

答案 0 :(得分:0)

这就像您的inline变量只需要这样:传入一个适当的变量,以便您可以读取该值。是的,这使方法声明变得复杂,但是它也清楚地向以后维护事物的任何人表明您正在将其用于特定的事物。感觉只是为了进行布局设置而进行的大量体操操,所以也许需要进行一些重构,以确保您不会走这条路?

好,编辑一下,以扔掉我在这里想的东西:

[Route("/{inline:bool=yes}/[controller]")]

我可能在变量声明中弄错了该语法(不确定我是否可以在此上下文中分配默认值,等等),但是值得一试吗?

但是,您会遇到麻烦,因为该路由可能与包含初始bool参数的其他路由没有区别,因此我倾向于将其移至该路由的后面,可能作为最终(可选)参数。