2
votes

I would like to create a route handler that will redirect to action/controller depends on the url. For example in ASP.NET MVC 4,5 we could create custom route class and override GetRouteData method and set own route values, e.g.

 public override RouteData GetRouteData(HttpContextBase httpContext){

  RouteData data = base.GetRouteData(httpContext);
  data.Values["controller"] = "SomeController";
  data.Values["action"] = "SomeAction";

  return data;
}

I tried to do the same in ASP.NET Core, but there is no posibility to override GetRouteData method. Are there any other tricks?

1
Could you use route constraints, that is, the IRouteConstraint interface? found blog post here: tommyb.com/…Jack

1 Answers

5
votes

Solution 1 by using Action filters

Action filters

public class SampleActionFilter : IActionFilter
{
    public void OnActionExecuting(ActionExecutingContext context)
    {
        var myController = ((MyController)context.Controller);
        context.Result = myController.RedirectToAction("SomeAction", "SomeController");
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {            
    }
}

Just note that method RedirectToAction() is part of MyController class. (Controller class already has this method, but it's protected)

Do not forget to register it Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options =>
    {
        options.Filters.Add(typeof(SampleActionFilter));
    });
}

Solution 2 by using IRouter

class MyRouter : IRouter
{
    private readonly IRouter _defaulRouter;

    public MyRouter(IRouter defaulRouter)
    {
        _defaulRouter = defaulRouter;
    }

    public async Task RouteAsync(RouteContext context)
    {
        // Set controller and action based on context.HttpContext.Request url
        context.RouteData.Values["controller"] = "Home";
        context.RouteData.Values["action"] = "About";
        await _defaulRouter.RouteAsync(context);
    }

    public VirtualPathData GetVirtualPath(VirtualPathContext context)
    {
        return _defaulRouter.GetVirtualPath(context);
    }
}

Startup.Configure

app.UseMvc(routes =>
{
    routes.Routes.Add(new MyRouter(routes.DefaultHandler));
});