Web API 2 and routing problem



  • I am probably being thick, but my scenario is.

    I have a controller called AccountController.cs.

    I have a 2 routes:

    POST https://<domain>/api/register
    
    POST https://<domain>/api/registerExternal
    

    I keep get an MVC error saying I have two matching routes in one controller. RegisterExternal is a route for dealing with registering people using OAuth mechanisms such as Facebook / G+ etc and Register is a regular sign up form. Both are being called via CORS from a Angular JS application.

    What the easiest way to solve this without renaming one the routes to something less descriptive?


  • FoxDev

    Are you using template-based routing or attribute-based routing?



  • Both It seems.


  • FoxDev

    Hmm… would you be able to post snippets that show the routing you have in place?



  • WebAPIConfig.cs:

    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );
    

    AccountController

    [RoutePrefix("api/Account")]
    public class AccountController : ApiController
    
    //POST api/Account/Register
    [AllowAnonymous]
    [HttpPost]
    [Route("Register")]
    public async Task<IHttpActionResult> Register(UserModel userModel)


  • My guess would be that you can't have two <domain>/api/ endpoints. I don't think you can combine paths like that.
    Edit: fuck if I can escape that correctly.



  • I will have a look tomorrow at moving everything to attribute based routing. At the moment I am writing some monster SQL queries for some features and I am not that good at SQL so it takes me about 4 times longer than everyone else.



  • That's where EF is nice 😉



  • Yeh well the performance sucks on EF compared to SPROCS.



  • Agreed, depending on the operation of course. (it's usually fine for CRUD operations )



  • I want the highest performance possible at the moment. Ironically the front end is the slowest due to viewstate madness.


  • FoxDev

    What if, instead of
    @lucas said:

    ```cs
    config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
    );

    you had
    ```cs
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id:int}",
            defaults: new { id = RouteParameter.Optional }
        );
    

    ❓
    I think @swayde's onto something with the route matching both attribute-based and template-based routes; that :int constrains the templated route to only accept an integer there, so using a string should match your attribute routing only.

    @lucas said:

    viewstate madness

    Is there a reason you're using WebForms instead of MVC?



  • @RaceProUK said:

    Is there a reason you're using WebForms instead of MVC?

    What I am working on is in a different project. There is a Webforms app that is for clients, I am building the admin portal that is an SPA using Angular 2.



  • @RaceProUK said:

    you had

    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id:int}",
        defaults: new { id = RouteParameter.Optional }
    );
    

    ❓I think @swayde's onto something with the route matching both attribute-based and template-based routes; that :int constrains the templated route to only accept an integer there, so using a string should match your attribute routing only.

    That won't work because my AccountController has a lot of methods other than those I mentioned. The two I mentioned conflicted in my OP.

    Maybe I should move everything to attribute routing (which I prefer). The Social Auth is more important than regular auth at the moment, so I don't care too much. But I want as much working as possible as I have a product demo on Friday.


  • FoxDev

    It is better to go either fully template- or fully attribute-based; mixing can be problematic. Personally, if you're going to have a lot of routes following well-known patterns, template-based may be better; you can control action names with the ActionName attribute. But if you want more precise control, attribute-based routing is the way to go ;)



  • I always want more control. I usually build these sorts of API with Silex (PHP) or Flask (Python).

    I've been mashing two projects together because I know I need to do a demo that looks like it works and basically ignoring best practice until after next week.



  • I basically moved everything to attribute routing and it works perfectly now.


Log in to reply