Asp.net core 2.2 API错误,请求匹配了多个端点

时间:2020-07-26 07:22:11

标签: api asp.net-core routes

我有这样的API控制器:

[Authorize]
[Route("api/[controller]")]
[ApiController]
public class ImageCourseController : ControllerBase
{
    #region Ctor
    private readonly GenericRepository<ImageCourse> _imageCourseGOP;
    public ImageCourseController(GenericRepository<ImageCourse> imageCourseGOP)
    {
        _imageCourseGOP = imageCourseGOP;
    }
    #endregion

    [HttpGet("/api/ImageCourse")]
    public async Task<ImageCourse> Get([FromQuery] int id)
    {
        return await _imageCourseGOP.ReadAsync(id);
    }

    [HttpGet("/api/ImageCourse")]
    public async Task<List<ImageCourse>> GetByCourseId([FromQuery] int courseId)
    {
        return await _imageCourseGOP.SelectAsync(n => n.CourseId == courseId);
    }
    ...
}

因此,方法Get路由为“ api / imagecourse?id = 1”,方法GetByCourseId路由为“ api / imagecourse?courseId = 3”。 我的问题是: 即使我有不同的路线,为什么仍会收到此错误?

2 个答案:

答案 0 :(得分:0)

收到错误消息是因为您有两个操作都使用相同的路线。

[HttpGet("/api/ImageCourse")]

使用[FromQuery]不会使路由有所不同,只是告诉它在哪里寻找该参数。

这是替代您的两个操作的一种替代操作:

[HttpGet("/api/ImageCourse")]
public async Task<object> Get([FromQuery] int? id, [FromQuery] int? courseId)
{
    object result;

    if(id.HasValue)
        result = await _imageCourseGOP.ReadAsync(id.Value);
    else if(courseId.HasValue)
        result = await _imageCourseGOP.SelectAsync(n => n.CourseId == courseId.Value);
    else
        result = null;

    return result;
}      

答案 1 :(得分:0)

如果您想根据查询字符串将请求与预期的端点进行匹配,则可以尝试实现自定义ActionMethodSelectorAttribute以根据查询字符串为给定请求启用或禁用操作。

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class CheckQueryStingAttribute : ActionMethodSelectorAttribute
{
    public string QueryStingName { get; set; }
    public bool CanPass { get; set; }
    public CheckQueryStingAttribute(string qname, bool canpass)
    {
        QueryStingName = qname;
        CanPass = canpass;
    }

    public override bool IsValidForRequest(RouteContext routeContext, ActionDescriptor action)
    {
        StringValues value;

        routeContext.HttpContext.Request.Query.TryGetValue(QueryStingName, out value);

        if (CanPass)
        {
            return !StringValues.IsNullOrEmpty(value);
        }

        return StringValues.IsNullOrEmpty(value);
    }
}

适用于操作方法

[HttpGet("/api/ImageCourse")]
[CheckQuerySting("id", true)]
[CheckQuerySting("courseId", false)]
public async Task<ImageCourse> Get([FromQuery] int id)
{
    return await _imageCourseGOP.ReadAsync(id);
}

[HttpGet("/api/ImageCourse")]
[CheckQuerySting("courseId", true)]
[CheckQuerySting("id", false)]
public async Task<List<ImageCourse>> GetByCourseId([FromQuery] int courseId)
{
    return await _imageCourseGOP.SelectAsync(n => n.CourseId == courseId);
}

此外,您可以参考this blog,其中介绍了如何定义ASP.NET Core Controller操作约束以匹配正确的操作。