Reputation: 1934
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
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