路由-一个项目中的WebAPI和MVC

时间:2019-05-31 15:35:30

标签: asp.net-mvc asp.net-web-api asp.net-core asp.net-mvc-routing

我有2个控制器。两者都与Bar(Foo的孩子)打交道。

其中之一是用于返回视图的MVC。

n

其中之一是用于API的API,该API位于“ api”的文件夹下。

func primecheck(number: Int) -> Bool {
    if number < 2 { return false }
    if 2...3 ~= number { return true }
    return !(2...Int(sqrt(Double(number)))).contains { number % $0 == 0 }
}

无需在FooBarController类中添加以下行,就可以访问API控制器(例如:/ api / foo / bar / {id})和MVC控制器(例如:/ FooBar / SomeAction)

  

[Route(“ Foo / Bar”)]

但是当我这样做时,路由混乱了,尝试访问/ Foo / Bar / SomeAction时出现以下错误

  

AmbiguousMatchException:该请求匹配了多个端点。匹配项:

     

Controllers.MVC.FooBarController.Index

     

Controllers.MVC.FooBarController.SomeAction

4 个答案:

答案 0 :(得分:1)

当您没有应用属性时,FooBarController将使用常规路由,默认情况下您可能已经使用了。通常,它具有索引作为默认操作,并允许您还指定操作名称,因此一切正常。

应用属性时,此控制器中的所有操作现在都使用属性路由。这两种路由类型没有组合,您只能使用其中一种。请注意

  

“通过属性路由,控制器名称和动作名称不起作用   选择动作的角色。”

docs source)。因此,这两个动作变得相同,它们的名称被忽略,并且不可能弄清楚要使用哪个动作。所以您需要帮助:

[Route("Foo/Bar")]
public class FooBarController : ControllerBase
{
    [Route("")]      // To make it default for "Foo/Bar"
    [Route("Index")] // Combines to define the route template "Foo/Bar/Index"
    public IActionResult Index()
    {
        // ...
    }

    [Route("SomeAction")] // Combines to define the route template "Foo/Bar/SomeAction"
    public IActionResult SomeAction()
    {
        // ...
    }
}

是的,它比较冗长。来自同一来源:

  

属性路由需要更多的输入来指定路由;的   常规的默认路由可以更简洁地处理路由。然而,   属性路由允许(并要求)精确控制哪个路由   模板适用于每个操作。

答案 1 :(得分:1)

如果您想将FooBarController.SomeAction/Foo/Bar/SomeAction路由,则可以尝试类似

    [Route("Foo/Bar/[action]")]
    public class FooBarController : ControllerBase
    {
            public IActionResult Index()
            {
                    // ...
            }

            public IActionResult SomeAction()
            {
                    // ...
            }
    }

答案 2 :(得分:0)

对于您的API控制器,我建议将Route更改为RoutePrefix["api"],这样,您的所有api方法都将仅包含路由(希望这与您的Home Controller名称不同)。

[RoutePrefix("api")]
public class MyApiController : ApiController 
{
    [HttpGet, Route("foo/bar")]
    public IHttpActionResult GetSomething()
    {
        //do something when routing to /api/foo/bar
    }

    [HttpPost, Route("foobar/foobar")]
    public IHttpActionResult GetSomething()
    {
        //do something when routing to /api/foobar/foobar
    }
}

对HomeController也有相同的建议(如果您确实要为其添加路由,则该类中的每个方法都将根据其方法名称进行路由,例如Index

[RoutePrefix("foo/bar")]
public class MyController : BaseController
{
    public IActionResult Index()
    {
        return View(); //or something
    }

    public IHttpActionResult Contact()
    {
        return View(); //or something
    }
}

答案 3 :(得分:0)

我设法使用以下方法使它(看来是)正常工作。

[Route("Foo/Bar")]
[Route("Foo/Bar/[action]")]
public class FooBarController : Controller
{
    [HttpGet("")]
    public IActionResult Index()
    {
        return RedirectToAction("SomeAction");
    }

    public IActionResult SomeAction()
    {
        return View();
    }

}