根据查询参数值将HTTP请求映射/路由到端点吗? asp.net core 3.x

问题描述 投票:0回答:1

我有一个客户端,需要使用其余的HttpGet调用来为多个请求命中相同的基本端点URL,每个调用都具有唯一的查询参数和值。我需要为每个请求映射的功能将由“ request”查询参数提供的值确定。是否可以在app.UseEndpoints()内部,端点函数上的属性或类似的简单解决方案中进行?

我对这部分内容有些陌生,文档中没有相应的示例。我到目前为止所拥有的(无效):

Startup.cs

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "test1",
            pattern: "serviceapi",
            constraints: new { request = "test1" }, //map action if param "request" value is "test1"?
            defaults: new { controller = "ServiceApi", action = "TestRequest1" }
        );
        endpoints.MapControllerRoute(
            name: "test2",
            pattern: "serviceapi",
            constraints: new { request = "test2" }, //map action if param "request" value is "test2"?
            defaults: new { controller = "ServiceApi", action = "TestRequest2" }
        );
    });

我想要的是当我使用邮递员将获取请求发送到“ {{url}} / api / serviceapi /request = test1&uniqueparam1 = foo”时,它将在我的代码中运行ServiceApi.TestRequest1()

[Route("api/[controller]")]
ServiceApiController.cs

    [HttpGet]
    public async Task<IActionResult> TestRequest1([FromQuery]string request, [FromQuery]string uniqueparam1)
    {
        return Ok($"TestRequest1: {request} - {uniqueparam1}");
    }

    [HttpGet]
    public async Task<IActionResult> TestRequest2([FromQuery]string request, [FromQuery]string uniqueparam2, [FromQuery]string uniqueparam3)
    {
        return Ok($"TestRequest2: {request} - {uniqueparam2}, {uniqueparam3}");
    }

我目前在此代码中遇到的错误是这两个函数都是候选函数:“ Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException:该请求匹配了多个端点。

谢谢!

asp.net-core httprequest endpoint
1个回答
0
投票

您需要自定义ActionMethodSelectorAttribute

1.QueryStringConstraintAttribute:

[AttributeUsage(AttributeTargets.Method,AllowMultiple =true)]
public class QueryStringConstraintAttribute : ActionMethodSelectorAttribute
{
    public string ValueName { get; private set; }
    public bool ValuePresent { get; private set; }
    public QueryStringConstraintAttribute(string valueName,bool valuePresent)
    {
        this.ValueName = valueName;
        this.ValuePresent = valuePresent;
    }
    public override bool IsValidForRequest(RouteContext routeContext, ActionDescriptor action)
    {
        var value = routeContext.HttpContext.Request.Query[this.ValueName];
        if(this.ValuePresent)
        {
            return !StringValues.IsNullOrEmpty(value);
        }
        return StringValues.IsNullOrEmpty(value);
    }
}

2.Controller:

[Route("api/[controller]")]
[ApiController]
public class ValuesController : Controller
{
    [QueryStringConstraint("uniqueparam1", true)]
    [QueryStringConstraint("uniqueparam2", false)]
    [HttpGet]
    public async Task<IActionResult> TestRequest1([FromQuery]string request, [FromQuery]string uniqueparam1)
    {
        return Ok($"TestRequest1: {request} - {uniqueparam1}");
    }
    [QueryStringConstraint("uniqueparam2", true)]
    [QueryStringConstraint("uniqueparam1", false)]
    [HttpGet]
    public async Task<IActionResult> TestRequest2([FromQuery]string request, [FromQuery]string uniqueparam2, [FromQuery]string uniqueparam3)
    {
        return Ok($"TestRequest2: {request} - {uniqueparam2}, {uniqueparam3}");
    }
}

3.Startup.cs:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    //...   
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();                
    });

}

参考:

https://stackoverflow.com/a/60770054/11398810

© www.soinside.com 2019 - 2024. All rights reserved.