Вопрос

I'm having issues getting my head around how route selection works. I have two route attributes set which are clashing with each other. They Are

[Route("{apikey}/Parent/{parentID}/Children/ChildrenDataFormat")]
[Route("{apikey}/Parent/{parentID}/{dataSelectionTypeA}/{dataSelectionTypeB}")]

The first route's last two parts are hard coded and will never change. The second route will bind into the method parameters.

If I remove the second route then the first route works fine but otherwise I get a 404. I presume the Route Matching is seeing a Guid followed by "Parent" and then ignoring the fact that "Children" and "ChildrenDataFormat" should be present and instead seeing 3 things follow so route 2 is a match.

If this a correct assumption and is there an obvious fix to make this work?

Это было полезно?

Решение 2

I'm still not sure what the exact issue was but I've managed to fix it by adding route constraints to all my variables. I.E my routes now look like

[Route("{apikey:guid}/Parent/{parentID:guid}/Children/ChildrenDataFormat")]
[Route("{apikey:guid}/Parent/{parentID:guid}/{dataSelectionTypeA:guid}/{dataSelectionTypeB:guid}")]

Другие советы

Oli

Since both your routes are attribute routes, they have no implicit order since both of them have the same number of path segments they both match leading to ambiguity.

The solution is to differentiate between them, what you did was to add constraints to only one of the routes match, another solution is to use order so first the more specific route (the one ending with /Children/ChildrenDataFormat).

Here is a simplistic example that shows order and how route values are being captures

public class ValuesController : ApiController
{
    [Route("api/values/MyName", Order = 1)]
    [Route("api/values/{name}", Order = 2)]
    public string Get()
    {
        object nameObj;
        Request.GetRouteData().Values.TryGetValue("name", out nameObj);

        if (nameObj != null)
        {
            // came from second route
            return "Route is {name} and name was: " + (string) nameObj;
        }
        else
        {
            return "Route is MyName so no name value is available";
        }
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top