The Razor compiler today defaults to generating a set of [RazjorInject] attributed properties on generated classes, even when the @inherit directive is used in the .cshtml file to set the base class to a custom type that does not derive from Microsoft.AspNetCore.Mvc.Razor.RazorPage. Furthermore, there is no way to disable this behavior declaratively via a directive so the classes generated from .cshtml files in ASP.NET Core projects always have these properties.
For example, the following /Slices/Hello.cshtml file:
@inherits RazorSlice
@tagHelperPrefix tagHelper:
<!DOCTYPE html>
<html>
<head>
<title>Hello</title>
</head>
<body>
Hello
</body>
</html>
will generate a class like so:
// AspNetCoreGeneratedDocument.Slices_Hello
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using MapAction.Razor;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Razor.Internal;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.Hosting;
[RazorCompiledItemMetadata("Identifier", "/Slices/Hello.cshtml")]
[CreateNewOnMetadataUpdate]
internal sealed class Slices_Hello : RazorSlice
{
[RazorInject]
public IModelExpressionProvider ModelExpressionProvider { get; private set; } = null;
[RazorInject]
public IUrlHelper Url { get; private set; } = null;
[RazorInject]
public IViewComponentHelper Component { get; private set; } = null;
[RazorInject]
public IJsonHelper Json { get; private set; } = null;
[RazorInject]
public IHtmlHelper<dynamic> Html { get; private set; } = null;
public override async Task ExecuteAsync()
{
WriteLiteral("<!DOCTYPE html>\r\n<html>\r\n<head>\r\n <title>Hello</title>\r\n</head>\r\n<body>\r\n Hello. The date is ");
Write(DateTime.Now.Date);
WriteLiteral("\r\n</body>\r\n</html>\r\n");
}
}
As can be seen from the generated code above, the only members actually required on the configured base type are WriteLiteral(string literal) and Write(object value). The other properties are not needed and indeed can get in the way due to them appearing in editor IntelliSense. Also, any custom property added via the @inject directive is indistinguishable from the default properties if trying to implement custom activation for these generated types, e.g. to set the property values from DI.
To improve the experience for scenarios where Razor .cshtml files are being used to generate classes other than Razor views or pages, we should make it simple to disable this property generation.
Some proposals to enable this:
- Disable the generation of these properties when the base type is set to non-Razor base type via
@inherits (preferred)
- Introduce MSBuild-based mechanism to disable adding of MVC generation defaults, e.g. item metadata
- Introduce a new directive that facilitates disabling default property generation
The Razor compiler today defaults to generating a set of
[RazjorInject]attributed properties on generated classes, even when the@inheritdirective is used in the .cshtml file to set the base class to a custom type that does not derive fromMicrosoft.AspNetCore.Mvc.Razor.RazorPage. Furthermore, there is no way to disable this behavior declaratively via a directive so the classes generated from .cshtml files in ASP.NET Core projects always have these properties.For example, the following /Slices/Hello.cshtml file:
will generate a class like so:
As can be seen from the generated code above, the only members actually required on the configured base type are
WriteLiteral(string literal)andWrite(object value). The other properties are not needed and indeed can get in the way due to them appearing in editor IntelliSense. Also, any custom property added via the@injectdirective is indistinguishable from the default properties if trying to implement custom activation for these generated types, e.g. to set the property values from DI.To improve the experience for scenarios where Razor .cshtml files are being used to generate classes other than Razor views or pages, we should make it simple to disable this property generation.
Some proposals to enable this:
@inherits(preferred)