Thank you for the video. 1. why did you choose to make your own extension to get data from header instead using FromHeader in action parameter 2. why did you choose to use exceptionfilter instead of using middleware? Thank you.
Thanks for commenting. I have created extension methods as I don't want to use the default model binder functionality. I want to be in charge of validating GUIDs for instance. For point two, I have created a dedicated video on that topic: ua-cam.com/video/jrkuJulrFok/v-deo.html
Thanks Mr.Dan for this awesome video 👍 Adding [Authorize] attribute to every controller is a headache special if the app has more than role e.g: Admins, Managers & Users. I was thinking to create a stand alone base controller for each role with their authorize attribute e.g:[Authorize (Roles="Users")] and make the controllers that the users should access inherit from UsersBaseController for example. Is there a better approach?
I'm not sure if your approach is the best in all scenarios. The main thing is that in most larger systems I worked, most of the controllers weren't dedicated to just one single role. For instance, I worked on a project management system and on the ProjectsController there were actions that different user roles could perform. But if you think that in your scenario you have this type of predictability, then I don't see a problem with taking the Authorize attribute to a base controller.
Either you run a regular integration test, and in that case you don't want to mock anything. If you want to unit test, you can instantiate your controller manually and provide all needed mocks in the constructor. So instead of having the DI container injecting things, you inject them. In my point of view, most problems with testing is that people misunderstand what each type of test is supposed to do. 1. In integration, you don't mock. 2. In unit test you can mock, and in that case you can instantiate your controllers by your own and provided all needed mocks in their constructor. People usually try to do a mix of those.
A question about the action filters, let's say we need to add some code before the return method like re-populate ViewBag then either return View("action") or RedirectToAction like below: if (!ModelState.IsValid) { code to execute... return RedirectToAction(nameof(Index)); } can something like that be done using action filters? Thanks for the great tutorial
I haven't worked with Razor views in a long while, but your proposal seems legit to me. The only thing is that probably you would have to return a RedirectToActionResult insteat of RedirectToAction. The idea is that in a filter you don't return an IActionResult. You need to set the Result on the ActionExecutionContext. But other then this, or use case seems to fit into the filter concept quite well.
I haven't really used Razor pages a lot, but I'm 99% sure it's applicable. You'd just have to create abase PageModel class that inherits PageModel and resolve all the common dependencies there.
Great video! You can move some of the code left (after refactoring) to a service class and the controller will be even leaner. Also, the abstraction level goes up a bit in the controller. Like you said, all depends on how you want to architect the solution, however what you show here I would say are best practices at an advanced level based on what I have seen in some projects.
It's not that they are best practices at an advanced level. I'm sure most of the developers are aware of them. As mentioned in the video, the problem is that controllers and controller actions are not big from the first go. They usually grow bigger over time. And the problem is that most people don't take the time to step back and evaluate that controller actions need to be refactored. What I am advocating in this video is just that: building a thought process that would allow you to always look critically at what needs to be done. Building a culture of technical excellence. That's what it's missing on most dev teams based on my experience.
I was just wondering how to avoid the ugly "try-catch" stuff from all the controllers and services. Great solution, thanks! :)
This is a a superb video, Dan. I learned a ton of things here. Thank you very much!
Great to hear!
Great content, I learnt a lot 💯👌🏽
Thank you for the video.
1. why did you choose to make your own extension to get data from header instead using FromHeader in action parameter
2. why did you choose to use exceptionfilter instead of using middleware?
Thank you.
Thanks for commenting. I have created extension methods as I don't want to use the default model binder functionality. I want to be in charge of validating GUIDs for instance.
For point two, I have created a dedicated video on that topic: ua-cam.com/video/jrkuJulrFok/v-deo.html
Thus is one of the video, I ve been searching for. Best explanations and new idea.. let's implement in my project.
Glad it was helpful!
Please what IDE is this you are using? Looks very cool
Jetbrains Rider.
Some excellent information Dan - great video and contents again!
Thanks again!
Thanks Mr.Dan for this awesome video 👍
Adding [Authorize] attribute to every controller is a headache special if the app has more than role e.g: Admins, Managers & Users. I was thinking to create a stand alone base controller for each role with their authorize attribute e.g:[Authorize (Roles="Users")] and make the controllers that the users should access inherit from UsersBaseController for example.
Is there a better approach?
I'm not sure if your approach is the best in all scenarios. The main thing is that in most larger systems I worked, most of the controllers weren't dedicated to just one single role. For instance, I worked on a project management system and on the ProjectsController there were actions that different user roles could perform.
But if you think that in your scenario you have this type of predictability, then I don't see a problem with taking the Authorize attribute to a base controller.
@@Codewrinkles thanks
But how can we test this controler with mock ILogger, or any other mock dependency, if we dont have constructor injected dependencies?
Either you run a regular integration test, and in that case you don't want to mock anything. If you want to unit test, you can instantiate your controller manually and provide all needed mocks in the constructor. So instead of having the DI container injecting things, you inject them. In my point of view, most problems with testing is that people misunderstand what each type of test is supposed to do.
1. In integration, you don't mock.
2. In unit test you can mock, and in that case you can instantiate your controllers by your own and provided all needed mocks in their constructor.
People usually try to do a mix of those.
A question about the action filters, let's say we need to add some code before the return method like re-populate ViewBag then either return View("action") or RedirectToAction like below:
if (!ModelState.IsValid)
{
code to execute...
return RedirectToAction(nameof(Index));
}
can something like that be done using action filters?
Thanks for the great tutorial
I haven't worked with Razor views in a long while, but your proposal seems legit to me. The only thing is that probably you would have to return a RedirectToActionResult insteat of RedirectToAction. The idea is that in a filter you don't return an IActionResult. You need to set the Result on the ActionExecutionContext. But other then this, or use case seems to fit into the filter concept quite well.
@@Codewrinkles Thanks, I'll look into ActionExecutionContext and see how to reform this scenario.
Great video indeed! Thanks a lot man.
Glad you liked it.
Equally applicable for Razor pages?
I haven't really used Razor pages a lot, but I'm 99% sure it's applicable. You'd just have to create abase PageModel class that inherits PageModel and resolve all the common dependencies there.
very helpful thanks.
Glad it was helpful!
well done.
Great video! You can move some of the code left (after refactoring) to a service class and the controller will be even leaner. Also, the abstraction level goes up a bit in the controller. Like you said, all depends on how you want to architect the solution, however what you show here I would say are best practices at an advanced level based on what I have seen in some projects.
It's not that they are best practices at an advanced level. I'm sure most of the developers are aware of them. As mentioned in the video, the problem is that controllers and controller actions are not big from the first go. They usually grow bigger over time. And the problem is that most people don't take the time to step back and evaluate that controller actions need to be refactored. What I am advocating in this video is just that: building a thought process that would allow you to always look critically at what needs to be done. Building a culture of technical excellence. That's what it's missing on most dev teams based on my experience.
Quite interesting
Glad you think that way. Didn't know you're watching my videos :)
Really great video, Thanks a lot!
Glad you liked it!