Jseb
Jseb

Reputation: 1934

How to set a default route in asp.net C# for certain controller action?

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.

Upvotes: 2

Views: 1001

Answers (1)

Leaky
Leaky

Reputation: 3636

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

Upvotes: 3

Related Questions