如何在一个URL中对控制器操作使用多态性

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

我试图将ASP.NET WEB API转换为ASP.NET CORE WEB API并出现错误

我在ASP.NET WebAPI中的代码

public class TestController : ApiController
{
    // GET /test
    public object Get()
    {
        return "get";
    }

    // GET /test?id={id}
    public object Get(string id)
    {
        return id;
    }

    // GET /test?id={id}&anyParam={anyParam}
    public object Get(string id, string anyParam)
    {
        return id + anyParam;
    }
}

config.Routes.MapHttpRoute("Controller", "{controller}");

尝试将其转换为ASP.NET Core 2.1 / 3.0

[ApiController]
[Route("{controller}")]
public class TestController : ControllerBase
{
    // GET /test
    public object Get()
    {
        return "get";
    }

    // GET /test?id={id}
    public object Get(string id)
    {
        return id;
    }

    // GET /test?id={id}&anyParam={anyParam}
    public object Get(string id, string anyParam)
    {
        return id + anyParam;
    }
}

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

而且我在ASP.NET Core中有

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

asp.net-core asp.net-core-webapi asp.net-core-2.1 asp.net-web-api-routing
2个回答
0
投票

我查看您在操作上生成的url,它们都是/test,它们会导致AmbiguousMatchException,因为您的参数是GET且是可选的。

我认为您可以在动作上使用相同的名称,但是您需要在动作上定义different ROUTE attribute(不同的URL)。例如。您不能在控制器操作上使用具有多态性的默认路由。

[Route("Home/About")]

MVC控制器现在在内部进行控制器映射UseEndpoints。

如果应用程序使用属性路由,则添加MapController。

Source

https://docs.microsoft.com/cs-cz/aspnet/core/mvc/controllers/routing?view=aspnetcore-3.0#attribute-routing


0
投票

感谢他的回答,我能够在Google上找到信息

ASP.NET Core的第一步,我们需要继承ActionMethodSelectorAttribute的类

public class RequireRequestValueAttribute : ActionMethodSelectorAttribute
{
    public RequireRequestValueAttribute(string name, string value = null)
    {
        Name = name;
        Value = value;
    }

    public string Name { get; }
    public string Value { get; }

    public StringComparison ComparisonType { get; } = StringComparison.OrdinalIgnoreCase;

    private bool ValueIsValid(object value)
    {
        return ValueIsValid(value?.ToString());
    }
    private bool ValueIsValid(string value)
    {
        if (Value == null)
        {
            return true;
        }

        return string.Equals(value, Value, ComparisonType);
    }

    public override bool IsValidForRequest(RouteContext routeContext, ActionDescriptor action)
    {
        var value = default(object);

        if (routeContext.RouteData.Values.TryGetValue(Name, out value) && ValueIsValid(value))
            return true;

        if (routeContext.RouteData.DataTokens.TryGetValue(Name, out value) && ValueIsValid(value))
            return true;

        if (routeContext.HttpContext.Request.Query.ContainsKey(Name))
        {
            var values = routeContext.HttpContext.Request.Query[Name];
            if (values.Count <= 0)
            {
                if (ValueIsValid(null))
                    return true;
            }
            else if (values.Any(v => ValueIsValid(v)))
                return true;
        }

        return false;
    }
}

然后我们可以向问题方法[RequireRequestValue("")]添加,控制器将如下所示:>

[ApiController]
[Route("{controller}")]
public class TestController : ControllerBase
{
    // GET /test
    public object Get()
    {
        return "get";
    }

    // GET /test?id={id}
    [RequireRequestValue("id")]
    public object Get(string id)
    {
        return id;
    }
}

但是它不能将两个相似的字段多态,在我的问题中输入id

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