C# Asp.net核心MVC2中的路由问题

C# Asp.net核心MVC2中的路由问题,c#,asp.net-core,routing,C#,Asp.net Core,Routing,我不能完全理解asp.net核心MVC2中的路由机制 以下是我所拥有的: 我已经建立了一个功能页面,将“材料”添加到“应用程序”中 调用此页面的URL为: 使用默认路由的: routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}" ); 其中57是应用程序id,因此我知道什么“应用程序”获得了新的“材料”。控制器中的索引方法如下所示,其工作方式与预期的相同: [Ht

我不能完全理解asp.net核心MVC2中的路由机制

以下是我所拥有的:
我已经建立了一个功能页面,将“材料”添加到“应用程序”中

调用此页面的URL为:

使用默认路由的:

routes.MapRoute(
    name: "default",
    template: "{controller=Home}/{action=Index}/{id?}"
);
其中57是应用程序id,因此我知道什么“应用程序”获得了新的“材料”。控制器中的索引方法如下所示,其工作方式与预期的相同:

[HttpGet] public IActionResult Index(string id)
{
    var model = GetModel(context, int.Parse(id));
    return View("Index", model);
}
到目前为止还不错现在我的问题是:
我想使用相同的控制器和视图来编辑“材质”。但为此,我需要Index()中的两个参数。我需要:

string applicationId
string materialId
作为参数

因此,我添加了一条新路线:

routes.MapRoute(
    name: "whatImTryingToAchieve",
    template: "{controller}/{action}/{applicationId?}/{materialId?}"
);
当然,我更新了控制器:

public IActionResult Index(string applicationiId, string materialId)
{            
    // Do stuff with materialId etc.
    // ...
    return View("Index", model);
 }
[Authorize(Roles = "Admins")] 
[Route("AddMaterial")]
public class AddMaterialController : Controller
{
    //....

    [Route("AddMaterial/{applicationId}/{otherid}")] // Nope. Nothing.
    [HttpGet] public IActionResult Index(string applicationId, string otherid) 
    { 
        return View(); 
    }

    [Route("AddMaterial/Index/{applicationId}")]  // Didn't work.
    [Route("AddMaterial/{applicationId}")]        // Didn't work either...
    [HttpGet] public IActionResult Index(string applicationId) 
    { 
        return View(); 
    }
}
我知道路由系统有一个特定的顺序。因此,我尝试在默认路由之前定义新路由。那没用。 然后我试着把它放在默认路线之后,这也不起作用

我通读了很多关于路由系统的信息,但似乎没有找到我的简单问题的答案:
如何添加另一条特定路线?

非常感谢您的帮助:)

编辑:基于属性的路由,如IgorsŠutovs所建议

控制器:

public IActionResult Index(string applicationiId, string materialId)
{            
    // Do stuff with materialId etc.
    // ...
    return View("Index", model);
 }
[Authorize(Roles = "Admins")] 
[Route("AddMaterial")]
public class AddMaterialController : Controller
{
    //....

    [Route("AddMaterial/{applicationId}/{otherid}")] // Nope. Nothing.
    [HttpGet] public IActionResult Index(string applicationId, string otherid) 
    { 
        return View(); 
    }

    [Route("AddMaterial/Index/{applicationId}")]  // Didn't work.
    [Route("AddMaterial/{applicationId}")]        // Didn't work either...
    [HttpGet] public IActionResult Index(string applicationId) 
    { 
        return View(); 
    }
}

属性基路由就到此为止。

我将提供我对所描述问题本质的主观意见。这个问题似乎可以重新表述为:“使用多个参数设计路由和解决此类情况的正确ASP.NET核心方法是什么?”

TLDR:使用

这是ASP.MVC 5中添加的新型路由。从那时起,旧的路由机制被认为是“基于传统的”。ASP.NET核心目前允许两者混合使用。我将提供一个详细的示例,说明如何使用基于属性的路由解决所描述的问题,因为新方法具有以下优点:

  • 路由信息更接近控制器操作,因此代码更容易理解和排除故障
  • 控制器名称及其方法与路由名称解耦
继续讨论解决方案。假设我们有两个模型:应用和材料。我将创建两个不同的控制器来管理每个控制器。从您的示例中,我了解到这些域实体之间的关系是一对多的,例如,一个应用程序可能有许多材料。这表明了以下途径:

GET: applications/{applicationId}
GET: applications/{applicationId}/materials/{materialId}
…回顾一下基本原则

应用程序控制器将如下所示:

[Route("applications")]
public class ApplicationController
{
    [HttpGet("{applicationId}")]
    public IActionResult Index(string applicationId)
    {
        // return your view
    }
}
[Route("applications/{applicationId}/materials")]
public class MaterialController
{
    [HttpGet("{materialId}")]
    public IActionResult Index(string applicationId, string materialId)
    {
        // return your view
    }
}
而MaterialController的外观如下所示:

[Route("applications")]
public class ApplicationController
{
    [HttpGet("{applicationId}")]
    public IActionResult Index(string applicationId)
    {
        // return your view
    }
}
[Route("applications/{applicationId}/materials")]
public class MaterialController
{
    [HttpGet("{materialId}")]
    public IActionResult Index(string applicationId, string materialId)
    {
        // return your view
    }
}
在Startup.cs的Configure方法中调用UseMvc(..)扩展方法现在可以简化为:

app.UseMvc();

希望你会发现它有用

我将就所述问题的本质提供我的主观意见。这个问题似乎可以重新表述为:“使用多个参数设计路由和解决此类情况的正确ASP.NET核心方法是什么?”

TLDR:使用

这是ASP.MVC 5中添加的新型路由。从那时起,旧的路由机制被认为是“基于传统的”。ASP.NET核心目前允许两者混合使用。我将提供一个详细的示例,说明如何使用基于属性的路由解决所描述的问题,因为新方法具有以下优点:

  • 路由信息更接近控制器操作,因此代码更容易理解和排除故障
  • 控制器名称及其方法与路由名称解耦
继续讨论解决方案。假设我们有两个模型:应用和材料。我将创建两个不同的控制器来管理每个控制器。从您的示例中,我了解到这些域实体之间的关系是一对多的,例如,一个应用程序可能有许多材料。这表明了以下途径:

GET: applications/{applicationId}
GET: applications/{applicationId}/materials/{materialId}
…回顾一下基本原则

应用程序控制器将如下所示:

[Route("applications")]
public class ApplicationController
{
    [HttpGet("{applicationId}")]
    public IActionResult Index(string applicationId)
    {
        // return your view
    }
}
[Route("applications/{applicationId}/materials")]
public class MaterialController
{
    [HttpGet("{materialId}")]
    public IActionResult Index(string applicationId, string materialId)
    {
        // return your view
    }
}
而MaterialController的外观如下所示:

[Route("applications")]
public class ApplicationController
{
    [HttpGet("{applicationId}")]
    public IActionResult Index(string applicationId)
    {
        // return your view
    }
}
[Route("applications/{applicationId}/materials")]
public class MaterialController
{
    [HttpGet("{materialId}")]
    public IActionResult Index(string applicationId, string materialId)
    {
        // return your view
    }
}
在Startup.cs的Configure方法中调用UseMvc(..)扩展方法现在可以简化为:

app.UseMvc();

希望你会发现它有用

你有什么错误?是否有投诉称存在多个可用操作,或者根本无法解决路由问题?@Kirk根本无法解决问题。可能是因为您在
索引
操作中拼写错误了
applicationid
?我不认为这是你的全部问题,但这不是一个好的开始。实际上可能是,我明天会试试。让我来问你:我处理这个问题的方式原则上正确吗?@serpent5这也不是问题。你会犯什么错误?是否有投诉称存在多个可用操作,或者根本无法解决路由问题?@Kirk根本无法解决问题。可能是因为您在
索引
操作中拼写错误了
applicationid
?我不认为这是你的全部问题,但这不是一个好的开始。实际上可能是,我明天会试试。让我问你:我处理这个问题的方式原则上正确吗?@serpent5这也不是问题。我确实觉得它很有用,我对你的答案投了赞成票。不幸的是,这在我的情况下不起作用。我通过将applicationId&materialId作为一个参数传递并手动解析它来解决这个问题。这是一个黑客,但至少它是有效的。事实上,即使在官方文档中,我也没有回答我的简单而有效的问题,这表明我将做更多的“黑客”来让asp.net核心真正为我工作。我确实发现它很有用,我对你的答案投了赞成票。不幸的是,这在我的情况下不起作用。我通过将applicationId&materialId作为一个参数传递给han并对其进行解析,解决了这个问题