Routing 使用Web API属性路由和RoutePrefix

Routing 使用Web API属性路由和RoutePrefix,routing,asp.net-web-api,asp.net-web-api-routing,Routing,Asp.net Web Api,Asp.net Web Api Routing,在使用web api时,如果使用[RoutePrefix()] 假设您有类似“MyReallyLongNamedClassController”的东西。默认路由是http:…com/api/MyReallyLongNamedClass。然后,应用程序使用名为Get、Post、Put等的方法(当然,除非使用动词修饰符) 如果我在我的控制器上放置了[RoutePrefix(“api/LongClass”)]的路由前缀装饰器,如何让web api仍然使用默认方法 也就是说,我希望名为“GetAll()

在使用web api时,如果使用
[RoutePrefix()]

假设您有类似“MyReallyLongNamedClassController”的东西。默认路由是http:…com/api/MyReallyLongNamedClass。然后,应用程序使用名为Get、Post、Put等的方法(当然,除非使用动词修饰符)

如果我在我的控制器上放置了
[RoutePrefix(“api/LongClass”)]
的路由前缀装饰器,如何让web api仍然使用默认方法


也就是说,我希望名为“GetAll()”的方法仍然映射到“api/LongClass”(当使用get头时)和“posthis(int-id)”仍然映射到“api/LongClass/{id}”(当使用post头时)

您不必担心RoutePrefix属性在内部是如何工作的。您可以使用RoutePrefix装饰控制器或操作,并可以根据您的设置调用操作。为了使
[RoutePrefix]
正常工作,您必须在操作中使用
路由
atribute

例如,在下面的控制器中,对url
api/longclass/GET
的所有
GET
请求将调用
GetAll
方法,对
api/longclass/POST
的所有
POST
请求将调用
PostThis

[RoutePrefix("api/longclass")]
public class MyReallyLongNamedClass: ApiController
{
    [Route("get")]
    public string GetAll(int id)
    { 
        return "result";
    }

    [Route("post")] 
    public string PostThis([FromBody] MyModel model)
    {
       var res=  _repository.Save(model);
       return res;
    }
}

您不必担心RoutePrefix属性在内部如何工作。您可以使用RoutePrefix装饰控制器或操作,并可以根据您的设置调用操作。为了使
[RoutePrefix]
正常工作,您必须在操作中使用
路由
atribute

例如,在下面的控制器中,对url
api/longclass/GET
的所有
GET
请求将调用
GetAll
方法,对
api/longclass/POST
的所有
POST
请求将调用
PostThis

[RoutePrefix("api/longclass")]
public class MyReallyLongNamedClass: ApiController
{
    [Route("get")]
    public string GetAll(int id)
    { 
        return "result";
    }

    [Route("post")] 
    public string PostThis([FromBody] MyModel model)
    {
       var res=  _repository.Save(model);
       return res;
    }
}

下面是我在不必用注释修饰所有方法的情况下解决问题的方法。我将RoutePrefix放在类级别,以及默认路由

[RoutePrefix("api/longclass")]
[Route("{id?}")]
public class MyReallyLongNamedClass: ApiController
{

    public string GetAll(int id)
    { 
        return "result";
    }


    public string PostThis([FromBody] MyModel model)
    {
       var res=  _repository.Save(model);
       return res;
    }
}

下面是我在不必用注释修饰所有方法的情况下解决问题的方法。我将RoutePrefix放在类级别,以及默认路由

[RoutePrefix("api/longclass")]
[Route("{id?}")]
public class MyReallyLongNamedClass: ApiController
{

    public string GetAll(int id)
    { 
        return "result";
    }


    public string PostThis([FromBody] MyModel model)
    {
       var res=  _repository.Save(model);
       return res;
    }
}

另一个选项:如果您只想更改路由中的控制器名称,则可以创建自定义控制器选择器:

public class CustomControllerSelector : DefaultHttpControllerSelector
{
    public CustomControllerSelector(HttpConfiguration configuration)
        : base(configuration)
    { }

    public override string GetControllerName(HttpRequestMessage request)
    {
        var name = base.GetControllerName(request);

        // Interpret "LongClass" as "MyReallyLongNamedClass"
        if (name == "LongClass")
            name = "MyReallyLongNamedClass";

        return name;
    }
}
然后,您可以在
WebApiConfig.register中注册控制器选择器:

config.Services.Replace(typeof(IHttpControllerSelector), new CustomControllerSelector(config));

这样做的好处是,您可以使用已映射的路由(使用
HttpRouteCollection.maphttprote()
定义),而不是使用属性路由。但是,如果出于其他原因需要使用属性路由,则您的解决方案可能更好。

另一个选项:如果您只想更改路由中的控制器名称,则可以创建自定义控制器选择器:

public class CustomControllerSelector : DefaultHttpControllerSelector
{
    public CustomControllerSelector(HttpConfiguration configuration)
        : base(configuration)
    { }

    public override string GetControllerName(HttpRequestMessage request)
    {
        var name = base.GetControllerName(request);

        // Interpret "LongClass" as "MyReallyLongNamedClass"
        if (name == "LongClass")
            name = "MyReallyLongNamedClass";

        return name;
    }
}
然后,您可以在
WebApiConfig.register中注册控制器选择器:

config.Services.Replace(typeof(IHttpControllerSelector), new CustomControllerSelector(config));

这样做的好处是,您可以使用已映射的路由(使用
HttpRouteCollection.maphttprote()
定义),而不是使用属性路由。但是,如果您出于其他原因需要使用属性路由,那么您的解决方案可能会更好。

当我这样做时,我得到以下错误{“消息”:“没有找到与请求URI匹配的HTTP资源”,找到了与名为“longclass”的控制器匹配的类型。}虽然我没有尝试您的解决方案以查看它是否有效,但我确实找到了另一个有效的解决方案。我将[RoutePrefix(“api/LongClass”)]和[Route({id?}])放在控制器级别,当我这样做时,我得到以下错误{“消息”:“找不到与请求URI匹配的HTTP资源。找不到与名为“longclass”的控制器匹配的类型。”}虽然我没有尝试您的解决方案,但我找到了另一个有效的解决方案。我将[RoutePrefix(“api/longclass”)]和[Route(“{id?}”)放在控制器级别