-->

Web API Routes to support both GUID and integer ID

2019-03-17 17:39发布

问题:

How can I support GET routes for both GUID and integer? I realize GUIDs are not ideal, but it is what it is for now. I'm wanting to add support for integers to make it easier for users to remember and communicate what should be unique "keys."

Example routes:

testcases/9D9A691A-AE95-45A4-A423-08DD1A69D0D1   
testcases/1234

My WebApiConfig:

public static void Register(HttpConfiguration config)
{
    config.MapHttpAttributeRoutes();
    var routes = config.Routes;

    routes.MapHttpRoute("DefaultApiWithAction", 
        "Api/{controller}/{action}");

    routes.MapHttpRoute("DefaultApiWithKey",
        "Api/{controller}/{key}",
        new { action = "Get" },
        new { httpMethod = new HttpMethodConstraint(HttpMethod.Get), key = @"^\d+$" });

    routes.MapHttpRoute("DefaultApiWithId", 
        "Api/{controller}/{id}", 
        new { action = "Get" }, 
        new { httpMethod = new HttpMethodConstraint(HttpMethod.Get) });

    routes.MapHttpRoute("DefaultApiGet", 
        "Api/{controller}", 
        new { action = "Get" }, 
        new { httpMethod = new HttpMethodConstraint(HttpMethod.Get) });

    routes.MapHttpRoute("DefaultApiPost", 
        "Api/{controller}", 
        new { action = "Post" }, 
        new { httpMethod = new HttpMethodConstraint(HttpMethod.Post) });
}

My controller (method signatures only):

[RoutePrefix("Api/TestCases")]
public class TestCasesController : PlanControllerBase
{
    [Route("")]
    public OperationResult<IEnumerable<TestCaseDTO>> Get([FromUri] TestCaseRequest request)

    [Route("{id}")]
    [HttpGet]
    public OperationResult<TestCaseDTO> Get(Guid id)

    [Route("{key}")]
    [HttpGet]
    public OperationResult<TestCaseDTO> Get(int key)

    ...
}

I'm getting an Internal Server Error when I attempt to call the resource using the integer. Any help is appreciated!

回答1:

Thank you to @SirwanAfifi! I had come across the Attribute Routing in ASP.NET article referred to in the SO question you mentioned, but apparently I didn't see the need for route attribute constraints at the time.

For me, it was using [Route("{id:guid}")] and [Route("{key:int}")] on my controller methods that did the trick. I also commented out the Http routes related to {id} and {key} in my WebApiConfig to verify that the attributes in the controller are responsible for doing the routing.