When pressing F12 (Go To Definition) on Controller in Visual Studio it shows you the abstract base class.
public abstract class Controller : IActionFilter, IFilterMetadata, IAsyncActionFilter, IDisposable
But when looking up Controller.cs on GitHub. It shows that it inherit from ControllerBase.
public abstract class Controller : ControllerBase, IActionFilter, IAsyncActionFilter, IDisposable
Why is this?
I am confused. Also, since HomeController inherit from Controller how can Controller inherit from ControllerBase when C# does not support multiple inheritance?
The two are from different points in time. So for example the file you linked to on GitHub is the current version of the file, note that it's from the Dev branch.
And more than likely you are not running code from the current dev branch.
If you click on the history button on GitHub for the file you linked to you will see the revision history for the file.
I checked the various version of this file by clicking on the <> button for each revision but non match the version of the code you are running. I see that the revision history for this file only goes back to Jan 22 2016. So prior to that the Controller code must have been defined in a different file or for some other reason the revision history was lost (Possibly when they renamed it from MVC 6 to Core MVC 1.0).
More than likely you are running code from RC1. That version of the Controller.cs on GitHub more closely matches what you are seeing: https://github.com/aspnet/Mvc/blob/6.0.0-rc1/src/Microsoft.AspNet.Mvc.ViewFeatures/Controller.cs It should match perfectly if it's the right version of the code but I see that it's still slightly different. It matches in the sense that it does not inherit from ControllerBase.
Also with regard to multiple inheritance. When HomeController inherits from Controller and Controller inherit from ControllerBase that's not multiple inheritance. Multiple inheritance would be if there were a ControllerBase and let's say a SomethingElse class and the Controller inherited from both of these classes in the controller definition. You are correct that C# does not support this.
Related
I have a base plugin class that cannot be resolved. It is like this:
package my.project
class NotificationController extends my.notification.plugin.NotificationController {...}
Upon building, the error I receive is
Error:(11, 1) Groovyc: unable to resolve class my.notification.plugin.NotificationController
Same thing for the Notification service.
Is this an Intellij thing or a Grails/Gradle thing? And is there a cure?
The answer is - you can't extend the controller because of the special processing grails applies to a controller. If one must do this, the base plugin should partition the controller "guts" into a regular class. Then, both the plugin and the main app can extend the regular class. Of course this is not quite the same as extending the plugin controller, but it seems to be as close as one can get. And this assumes one has control of the plugin class code...
If I have set up a project with lots of controllers and views, how could I use them in another project in ASP.NET Core? I tried refering the project but when I use the views in previous project it just return NOT FOUND.
While it is reasonable to create your own ControllerFactory, I found it more convenient to define all my Controllers in each project, but derive them from Controllers in my Shared project:
namespace MyProject1.Controllers
{
public class MyController : MySharedProject.Controllers.MyController
{
// nothing much to do here...
}
}
namespace MySharedProject.Controllers
{
public abstract class MyController : Microsoft.AspNetCore.Mvc.Controller
{
// all (or most) of my controller logic here...
}
}
This has the added benefit that you have a place to put your Controller logic that differs from project to project. Also, it is easier for other developers to quickly find your Controller logic because the Controllers exist in the standard place.
Regarding whether this is advisable, I think it absolutely is. I've created some common Account Management logic that I want to share between projects that otherwise have very different business logic. So I'm sharing my Account and Admin Controllers, but the other Controllers are specific to their respective projects.
ASP.NET WebAPI has a much appreciated ability to discover ApiController classes in external DLLs even if those DLLs are not referenced. For example, I may have MyWebApiProject that has a set of ApiControllers. I could then create a completely separate project called MyApiProjectPlugin that contains ApiController classes also. I have been able to add the MyApiProjectPlugin.dll file to the bin folder with the first MyApiProject.dll and the original project will discover all the controllers in the plugin project. I really like that ability.
However, What I would like to do is be able to add the plugin project to a sub directory inside of the bin folder. Something like bin/plugins. When I tried this, the original MyApiProject was unable to discover the plugin's controllers.
Is there a simple way to get WebAPI to look for ApiController classes in the bin's subdirectories? If I can avoid rewriting a controller factory from scratch I would like to.
You can write an assembly resolver.
public class PluginsResolver : DefaultAssembliesResolver
{
public override ICollection<Assembly> GetAssemblies()
{
List<Assembly> assemblies = new List<Assembly>(base.GetAssemblies());
assemblies.Add(Assembly.LoadFrom(#"<Path>\MyApiProjectPlugin.dll"));
return assemblies;
}
}
In the Register method in WebApiConfig, register the resolver.
config.Services.Replace(typeof(IAssembliesResolver), new PluginsResolver());
I have a controller that I want to generate documentation for using ASP.NET Web API Help Pages.
When I directly inherit from ApiController the documentation appears:
public class ExampleController : ApiController
But when I inherit from a base controller, it is omitted:
public class ExampleController : ApiBaseController
...
public class ApiBaseController: ApiController
I have switched to delegation rather than inheritance, but I wanted to know how to make it work with inheritance.
Here is a tip I picked up in my experimentation.
The documentation leans heavily on the routes in your API config. If your controller isn't covered by a route, it won't show up. Additionally, the order of the routes in your API config is the order of the operations in your documentation.
To cover both of these points I have created named routes for each controller. This has the added benefit of making each route specific, rather than a single route with lots of optional bits. This ensures all my operations appear in the documentation, in a good order.
I have also added the API tester so the API can be called directly from the documentation.
Check the permissions in your base class. I had the same issue and is was a result of methods that should have been set as internal being protected.
Make sure that all your methods that need to be accessed by the parent item are set to internal and any methods that override the ApiController are set to protected.
Post your code if it still doesn't work.
Works like Gravy :)
This is the layout I'd like to use for controllers in CodeIgniter:
(base) editor
(extend) design
(extend) content
(extend) ...php
...where editor is a base class and design, content, etc. controllers extend editor. The editor class will have methods that are publicly accessible from the extended classes URL segments.
I've read some topics on here, and they recommended:
Library - this won't work as methods won't be publicly accessible (am I correct?)
Put base class in the same file as extended class and name the controller that - this won't work since I need to extend from multiple places.
Put all the files in the controllers folder, add require statements to each extended class - is this bad form?
I'm new to CI. What's the proper/correct way to handle this?
Thanks!
http://www.ellislab.com/codeigniter/user-guide/general/core_classes.html
extend the core CI controller with MY_Controller, then extend MY_Controller with your other controllers. all the other retain the functionality in MY and MY retains the functionality of the base controller
There is also this article which allows more controllers that don't have the MY_ prefix, which I use and find VERY useful!
http://philsturgeon.co.uk/blog/2010/02/CodeIgniter-base-Classes-Keeping-it-DRY