Home > Mobile >  ASP.NET Core 6 MVC : how to implement layout logic?
ASP.NET Core 6 MVC : how to implement layout logic?

Time:03-10

I need to implement some logic to all views globally. I have a _layout view. How can I run logic (via a controller) for the shared layout?

I'm looking to implement the following logic:

  • Check if the user can perform an action of controller (if not, return to the previous page)
  • Check if the user account is active (after login, a user account can be disabled) (if not, log out and return to the login page)
  • Update the user log (update a table to save the IP and the time of the last user request to the server)
  • Hide controls for the user (prevent the user from seeing a control or changing any data)

In ASP.NET Web Forms 4, I created a class called Users, and this class was called inside of the master page's .cs code behind.

How can I accomplish something similar in ASP.NET Core MVC?

CodePudding user response:

First I wouldn't recommend a Controller for the _layout page as this is not how the MVC architecture works.

You could create a view using the layout page, like UserView.cshtml.

Then you can create a UserController.cs and your actions in it.

I hope I could help.

CodePudding user response:

Welcome to MVC! The transition from ASP.NET Web Forms can be a bit frustrating as the programming models are so different. But once you get past the conceptual hurdles, you'll find a lot of tasks are much cleaner and easier to maintain.

I struggled with a similar challenge myself when migrating from ASP.NET Web Forms to, first, the ASP.NET MVC Framework and, later, ASP.NET Core MVC. There are a few common strategies for addressing problems like this, which I'll summarize below.

Custom Filter

For most of what you're talking about, the textbook solution is to create an custom filter, which is a piece of code that can be applied to multiple actions or controllers, and will be called at various stages of execution (e.g., before or after an action). You can also wrap filters in attributes, which makes it easy to apply them as an annotation to any action or controller. You can also register filters globally so they apply to all actions on all controllers. Filters are especially useful when you want to validate a request based on the current request—including potentially the current user.

View Component

Another approach, introduced with ASP.NET Core, is a View Component, which is a bit like a partial view, except that it has code behind it that operates a lot like a controller. This is useful if you need reusable components that share their own model on every page of your site, as it allows that to be constructed independently of any one action, while being shared across multiple views.

The textbook example of a view component is a login control, which receives a view model with information about the currently authenticated user, and uses that to conditionally display e.g., a sign-in or sign-out link.

Aside: I often use view components for centralizing my navigation, so I don't need to relay the data for the navigation down to every single view model. That's beyond what you're asking about here, but may help further conceptualize when a view component is useful.

Business Object

From a code organization perspective, you can still maintain much of the logic inside a custom User class, or even as extension methods off of e.g. the ASP.NET Core ClaimsPrincipal class (which is returned from the HttpContext.User property). Determining what the current state of the user is for the purposes of e.g. authorization makes sense in a separate class; handling the ASP.NET Core response to that (such as redirection to a previous page) belongs in the filter or view component.

And, of course, you can also relay (properties from) this class to your view via your action's or view component's view model if you need to rely upon them to customize the user interface.

Conclusion

There are obviously a number of approaches here—as well as some I haven't mentioned, such as implementing a base controller—but this should help get you started in thinking about how to centralize site-wide business logic without needing to repeat it in every action of every controller, or polluting your _Layout.cshtml with logic that would normally reside in a controller.

  • Related