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?


  • sockdevs

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



  • Both It seems.


  • sockdevs

    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.


  • sockdevs

    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 }
        );
    

    :question:
    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 }
    );
    

    :question: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.


  • sockdevs

    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
 

Looks like your connection to What the Daily WTF? was lost, please wait while we try to reconnect.