2

How can i restraint certain route not to be used.

In my startup.cs I have two mapendpoint

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "botConfiguration",
                    pattern: "bot/{botID}/{controller=Home}/{action=Index}/{id?}"); 

                endpoints.MapControllerRoute(
                     name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });

In my controller

        public IActionResult Setting(int botID)
        {

            //botConfigRepository.GetAll();
            return View();
        }

The idea I would like to say if botID is not defined in my route, then you can't call this action, or it would redirect to the main page of some sort.

Now I know I coudl do an

if (botID == 0 ){
   return RedirectToAction("Index");
}

Of some sort but to write this for every action sound kind of painfull.

2
  • Have you try to use ActionFilter? Commented Mar 2, 2021 at 21:12
  • No i didnt not try this action filter, ill have to look into it Commented Mar 2, 2021 at 21:37

1 Answer 1

3

Sure, ASP.NET Core supports multiple ways of implementing cross-cutting concerns. Depends on how crude you want to go, but it could be as simple as adding a custom middleware delegate like the following:

// In Startup.cs
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // Placed before app.UseEndpoints()
    app.Use(async (ctx, next) => {
        if (!ctx.Request.Query.ContainsKey("botID") && !ctx.Request.Path.Value.Contains("Index"))
            ctx.Response.Redirect("Index");
        else
            await next();
    });
}

(The second condition is there only to prevent cascading redirects.)

A middleware is basically the topmost constituent part of the request processing pipeline, which is essentially a chain of responsibility structure where each middleware can pass control or short-circuit. ASP.NET's own components are implemented as a middleware, for example the authorization middleware and the routing middleware. And the order these are added inside Startup.cs/Configure() determines the order of their execution.

So, if you want to achieve something relatively low-level, the cleanest way is often to use a middleware for it. You can also add a proper middleware class with app.UseMiddleware().

(One thing you should look out for is that middleware have a singleton lifetime, so injecting request-scoped services into them is problematic. See this question.)

As an alternative solution you can use a globally registered ActionFilter to achieve the same result, as someone commented:

public class MyActionFilter : IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext context) {}

    public void OnActionExecuting(ActionExecutingContext ctx)
    {
        if (!ctx.HttpContext.Request.Query.ContainsKey("botID") && !ctx.HttpContext.Request.Path.Value.Contains("Index"))
        {
            ctx.Result = new RedirectResult("Index");
        }
    }
}

// Register it in Startup.ConfigureServices()
services.AddMvc(options => options.Filters.Add(new MyActionFilter()));

If you have additional requirements, feel free to comment, and I can try to address them. :)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.