如何在ASP.NET CORE 3.0中配置路由以使用带有[FromQuery]参数的重载[HttpGet]方法? [英] How to configure routing in ASP.NET CORE 3.0 to use overload [HttpGet] method with [FromQuery] parameters?

查看:1112
本文介绍了如何在ASP.NET CORE 3.0中配置路由以使用带有[FromQuery]参数的重载[HttpGet]方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对不起,标题我不好,请告诉我您是否有更好的标题来描述问题的内容.

Sorry about the title, I'm not good at them, let me know if you know any better title to describe the content of the question.

所以我有2种方法,第一种是获取所有列表项,第二种也是获取所有列表项,但是,第二种方法中有一个查询参数,我用它来过滤,第二种方法也返回与第一种方法不同的对象.由于我有2个Http get方法可以走相同的路线,因此当我调用其中一种方法时,我会得到:

So I have 2 methods, the first one is to get all the list items, and the second is to get all the list items too, however, there is a query parameter on the second method, that I use to filter, and the second method also returns a different object than the first method. Since I have 2 Http get methods that go to the same route, when I call one of the methods I get:

Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException: 请求匹配多个端点.符合条件:.....

Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException: The request matched multiple endpoints. Matches: .....

如何在不合并这两种方法或不使用可选参数或更改一种方法的路径的情况下解决此问题?如果可能的话?

How do I solve this without merging the 2 methods or making use of optional parameters, or changing the path of one method? if possible??

示例代码:

// GET: api/Resources
[HttpGet]
public async Task<ActionResult<ICollection<Data>>> GetAll()
{
    return Ok(await Service.GetAll());
}

// GET: api/Resources
[HttpGet]
public async Task<ActionResult<Data2>> GetAll([FromQuery]int parameter)
{
    return Ok(await Service.GetAll2(parameter));
}

在我的configure方法中:

Inside the configure method I have:

app.UseHttpsRedirection();

app.UseRouting();

app.UseAuthentication();

app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
});


根据注释的建议尝试使用这样的配置中的操作...


Tried as suggested by comments to make use of actions in a configuration like this...

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute("default", "{controller}/{action}/{id?}");
});

它没有用,因为当我执行get请求时,调用了错误的方法, 例如,第一个getall方法:api/resources/getall 下面的方法被触发,而不是导致错误,因为getall不是int ...

It didn't work because the wrong method gets called when I do a get request to, for example, the first getall method: api/resources/getall the method below gets triggered instead causing an error since getall is not an int...

// GET: api/Resources/5
[HttpGet("{id}")]
public async Task<ActionResult<Data>> GetById(int id)
{
    return Ok(await Service.GetById(id));
}


复制示例>> https://drive.google.com/open?id = 15EB1_kK-c_qyhRS0QvVlKnhuUbFjyN12

现在要执行的操作必须更改控制器中的属性路由...

Got the actions working now, had to change the attribute routing in the controller...

[Route("api/[controller]/[action]")]
[ApiController]
public class ResourcesController : ControllerBase
{
    // GET: api/Resources/GetAll
    [HttpGet]
    public ActionResult<ICollection<string>> GetAll()
    {
        return Ok(new List<string>() { "foo", "bar" });
    }

    // GET: api/Resources/GetAll2?parameter="bar"
    [HttpGet]
    public ActionResult<string> GetAll2([FromQuery]string parameter)
    {
        return Ok(parameter);
    }

    // GET: api/Resources/GetById/5
    [HttpGet("{id}")]
    public ActionResult<int> GetById(int id)
    {
        return Ok(id);
    }
}

尽管由于没有不同的路径就不可能实现这一点,所以我将只更改一种方法的路径,而不是在控制器中使用动作,并且在调用方法时必须在路径中添加动作名称.

Though since it's not possible to achieve this without having different paths, I'm going with changing the path of only one method instead of using actions in the controller and having to add the action name in the path when calling the methods.

几周后我碰到的其他可能可行的方法(未测试)是使用路由约束,如

Something else I came across a few weeks later that may work(didn't test) is the use of route constraints as seen in this video.

推荐答案

作为参考,我创建了一个新的Web api asp.net core 3项目.

As reference I have created a new web api asp.net core 3 project.

也可以说,例如,您在 Startup.cs中注册了默认路由. endpoints.MapDefaultControllerRoute();

Also let's say for example you had the default route registered on your Startup.cs. endpoints.MapDefaultControllerRoute();

添加

[Route("api/[controller]/[action]")]
[ApiController]

在控制器启动时,它会覆盖启动程序,因此您不必担心其他控制器.

At the start of your controller does override your Startup so you do not have to worry about your other controllers.

另外, Id是可选参数也无法实现此目的. 你会变得模棱两可.由于GetAll()和GetAll(int参数)完全相同,因为我们已将参数声明为可选参数. 这就是为什么您会收到错误消息.

Also you cannot achieve this with the Id being optional parameter. You would get ambiguity. Since GetAll() and GetAll(int parameter) are precisely the same, since we have declared the parameter as optional. This is why you get the error.

using Microsoft.AspNetCore.Mvc;

namespace WebApiTest.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class ResourceController : ControllerBase
    {

        [HttpGet]
        //api/Resource/GetAll
        public IActionResult GetAll()
        {
            return Content("I got nth");
        }

        //GET: //api/Resource/GetAll/2
        [HttpGet("{parameter}")]
        public IActionResult GetAll(int parameter)
        {
            return Ok($"Parameter {parameter}");
        }

    }
}

还要注意,在第二个GetAll()中,我在HttpGet参数中添加了它.

Also notice that at the second GetAll() i added in my HttpGet the parameter.

这只是为了更新路由引擎,该路由将具有一个参数,因为在我注册文件的通用级别上,直到执行操作为止.

This is just to update the routing Engine that this route will have a parameter since at the generic level at the top of my file i am registering until the action.

对于更多参数,您可以执行以下操作. [HttpGet({parameter}/{resourceId})].

For more parameters you can do sth like this. [HttpGet({parameter}/{resourceId})].

然后,您的路线将类似于此 api/Resource/GetAll/2/4 .

Then your route would work similar to this api/Resource/GetAll/2/4.

这篇关于如何在ASP.NET CORE 3.0中配置路由以使用带有[FromQuery]参数的重载[HttpGet]方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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