aspnet / Mvc

[Archived] ASP.NET Core MVC is a model view controller framework for building dynamic web sites with clean separation of concerns, including the merged MVC, Web API, and Web Pages w/ Razor. Project moved to https://github.com/aspnet/AspNetCore
Apache License 2.0
5.61k stars 2.14k forks source link

Allow the full class name of the controller to be used wherever ControllerName is required #5535

Closed ghost closed 7 years ago

ghost commented 7 years ago

The nameof() operator fills a void that has been missing for quite a while, but it doesn't work when a method requires a controller name, as nameof() will return the full class name (ending with "Controller"). It would be nice if all these methods accepted both the short class name (w/o "Controller") and the full class name. While the short class name really isn't needed any longer with this operator, it needs to be kept around for existing code.

frankabbruzzese commented 7 years ago

This is an old story. A similar request was done in previous Mvc versions, but never accepted by the Asp.net team. I think, that the best solution is not using string names at all, but using strobgly typed helpers that refer the controller type and methods. In Mvc5 there was an exstension for this...For asp.net core I found this project that might be usefull: https://github.com/ivaylokenov/AspNet.Mvc.TypedRouting

iscifoni commented 7 years ago

@Kaelum You can use the ControllerAttribute

[Controller] public class Home { }

so MVC use Home class as a controller and nameof() return "Home"

https://github.com/aspnet/Mvc/blob/760c8f38678118734399c58c2dac981ea6e47046/test/Microsoft.AspNetCore.Mvc.Core.Test/Controllers/ControllerFeatureProviderTest.cs#L403

ghost commented 7 years ago

@frankabbruzzese the C# team added the nameof() operator for MVC. If it isn't going to work as needed, then the operator needs to be removed from the language.

@iscifoni that doesn't work in MVC 5, as there doesn't appear to be a ControllerAttribute that I can find. If that is an ASP.NET Core only attribute, that doesn't help at this time. We can't move to ASP.NET Core until all of the tooling is fully functional, and they only released the first beta of the tooling yesterday.

We need this to work under C# 6, Razor with C# 6, .NET Framework 4.6.2 , ASP.NET MVC 5, and MSBuild, as that is the latest production available releases available. Anything else is considered beta and can only be used in playgrounds.

frankabbruzzese commented 7 years ago

@Kaelum , Here the problem is not nameof that being a C# operator doesnt know anything about MVC and Controllers, but the fact that ActionMethods are referenced through strings instead of strongly typed constructs. For sure C# compiler that handles nameof can no way have a dependecy on asp.net dlls, but asp.net itself should have better ways to reference Action methods.

ghost commented 7 years ago

@frankabbruzzese I think you are misunderstanding the issue. nameof(HomeController.About) returns About, and all of the MVC methods that require an Action name, work. nameof(HomeController) returns HomeController, which is what it should return. However, NONE of the MVC methods that require the controller name will accept it, because they will only accept Home.

Looking for a view will iterate through 8 different ways of defining a view name. So, why can't these MVC methods allow for full controller names?

frankabbruzzese commented 7 years ago

@Kaelum , If the Controller postfix is the only problem, just define a string extension method that removes the Controller postfix, say Controller(). This way you may write something like nameof(MyController).Controller() to get the right name accepted by all methods(in the example "My").

ghost commented 7 years ago

@frankabbruzzese I am already doing that, but I shouldn't have to.

ivaylokenov commented 7 years ago

@Kaelum This package may do the job for you: https://github.com/ivaylokenov/ASP.NET-MVC-Lambda-Expression-Helpers It is compatible with MVC 5.

frankabbruzzese commented 7 years ago

@Kaelum, I agrre with you nameof(MyController).Controller() is a dirty trick, but the same usage of nameof is a "patch" to avoid writing "magic strings". The fact remains that methods accept controllers and action methods as simple strings that is "dangerous", create problems when re-engineering code, etc. The problem you mentioned is one of several issues that appear during software maintenance due to "magic string" usage.

Thus, in my opinion the best solution is the usage of "true" strongly typed helpers. @ivaylokenov is the author of the software I initially proposed you and say it is compatible also with Mvc5. In my opinion at moment that is the best option.

For sure the team will not accept your suggestions that helpers accept also full controller names, since this might create compatibility problems with existing software (very unlekely to occurr...since they may occur when there are controllers named like MyControllerController, ie with several "Controller postfixes"). Similar requests were already declined in the past (since Mvc4...if I remember)

The hoipe is in a future version they will introduce strongly typed helpers like the ones of @ivaylokenov that are the true solution of the problem.

ghost commented 7 years ago

The thing that all of you are completely glossing over, is the fact the C# 6 was not out at the time that these "denials" were issued. The nameof() operator in C# 6 was created for this specific purpose, which nullifies all of those previous denials, making them moot. Having a controller with a name "...ControllerController" was never supported, and very much discouraged, so that should not be a concern of the MVC team. I will wait for the response of an official team member.

Eilon commented 7 years ago

Closing this because there are no plans to change this behavior in MVC.