Skip to content

Makes razor views (.cshtml) files reloadable #34248

@pranavkm

Description

@pranavkm

Follow up to dotnet/runtime#54633 to support reloading razor files


Proposed API

namespace Microsoft.AspNetCore.Razor.Hosting
{
+     [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
+     public sealed class RazorFileIdentifierAttribute : Attribute
+     {
+         public RazorFileIdentifierAttribute(string identifier);
+         public string Identifier { get; }
+     }
}

When a reloadable type is reloaded, the compiler tells us what type was reloaded, but not what it is replacing. It's up to the system to determine what's being replaced. For Razor, we can use the path as a way to do this (this is fairly similar to what runtime compilation does). In our current implementation, razor creates an attribute that tells it what it's path is, but this is an assembly level attribute that is not updated on a hot reload event:

[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCoreGeneratedDocument.Views_Home_Index), @"mvc.1.0.view", @"/Views/Home/Index.cshtml")]

The proposal is to add a type level attribute that we can have instead:

+ [global::System.Runtime.CompilerServices.CreateNewOnMetadataUpdateAttribute] // Reloadable type
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorFileIdentifierAttribute(@"/Views/Home/Index.cshtml")]  // This attribute can be used to determine what file needs to be replaced.
internal sealed class Views_Home_Index : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>

Usage examples

This is a compiler generated attribute that we do not expect users to use

Alternative designs

We could remove the restriction that prevents RazorCompiledItemAttribute only apply to attributes and additionally apply it to types:

[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCoreGeneratedDocument.Views_Home_Index), @"mvc.1.0.view", @"/Views/Home/Index.cshtml")]
[global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCoreGeneratedDocument.Views_Home_Index), @"mvc.1.0.view", @"/Views/Home/Index.cshtml")]
internal sealed class Views_Home_Index ...
{

}

Risks

n/a

Metadata

Metadata

Assignees

Labels

DoneThis issue has been fixedapi-approvedAPI was approved in API review, it can be implementedarea-mvcIncludes: MVC, Actions and Controllers, Localization, CORS, most templatesenhancementThis issue represents an ask for new feature or an enhancement to an existing onefeature-hot-reloadThis issue is related to the Hot Reload feaature

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions