ploeh / Hyprlinkr

A URI building helper library for ASP.NET Web API
MIT License
197 stars 34 forks source link

RouteLinker produces wrong URI with action defined on abstract base class #10

Closed dhilgarth closed 12 years ago

dhilgarth commented 12 years ago

Assume the following scenario:
You have an generic abstract class deriving from ApiController. This class implements the default actions for GetAll, GetById, Add, Update and Delete.
Now you have several controllers deriving from that base class, e.g.

public class SubjectsController : CrudControllerBase<SubjectModel>
{
}

When RouteLinker is asked for an URI for one of the actions of the base class, it returns an URI with the baseclass as controller, although that URI is not working. The correct URI would be to use the controller supplied as type argument.

linker.GetUri<SubjectController>(c => c.GetAll());

This produces http://<host>/api/crudbase´1 instead of http://<host>/api/subjects.

I think the problem is two-fold:

  1. DefaultRouteDispatcher sets the route value controller to the class that declares the action method. However, a new implementation of IRouteDispatcher doesn't solve that problem because the generic type argument passed to RouteLinker.GetUri<T> is not forwarded to IRouteDispatcher
  2. Simply not setting the controller in the implementation of IRouteDispatcher leads to an ArgumentNullException, because RouteLinker doesn't provide a fallback value in case the dispatcher didn't provide a controller.

I think the solution needs to be to forward the specified controller type to IRouteDispatcher.

I created two failing tests to better demonstrate my findings: https://github.com/dhilgarth/Hyprlinkr/blob/bug/ControllerWithAbstractBaseClass/Hyprlinkr.UnitTest/RouteLinkerTests.cs#L212

ploeh commented 12 years ago

Thanks for reporting this. I've pushed a fix to master. Can you verify whether it fixes your particular problem too?

dhilgarth commented 12 years ago

Looks good, thanks.

ploeh commented 12 years ago

The fix is now live as 0.5.0. Can the issue be closed?

dhilgarth commented 12 years ago

Yes