dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.51k stars 10.04k forks source link

Hotreload not working with .cshtml files #38809

Closed HybridSolutions closed 1 year ago

HybridSolutions commented 2 years ago

In a .NET 6 Core Web app mixed with Blazor components, Hotreload is not working fully. If I update anything on a Blazor component (.razor file), the browser updates in real time. If I update a .cshtml file, Hotreload happens, but changes are not updated in the browser. I have to refresh.

Is this behavior known? Any solution?

pranavkm commented 2 years ago

Does your app reference the RuntimeCompilation package? With dotnet-watch, we let runtime compilation take over since they're both designed to solve the same problem.

HybridSolutions commented 2 years ago

What is the full name of the package? It's Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation?

pranavkm commented 2 years ago

Yup, that's the one. You could remove the package reference if you are currently only using it during development.

HybridSolutions commented 2 years ago

Yup, that's the one. You could remove the package reference if you are currently only using it during development.

I don't have that package Installed. Changing some text in my .cshtml file does nothing after save. The checkmark appears in the top left corner and I get

eCM.Web (Web server): Sending updates to running application
eCM.Web (Web server): Updates applied successfully

but in the browser, nothing happens. Any ideas?

Aquaritek commented 2 years ago

Not much help here, but I have the same issue. Running on latest VS 2022 Preview with a brand new Blazor WASM app using the built-in templates. Selected all the fixins except docker support.

If I edit server-side code such as API controllers. Hot reload works wonders. If I edit Identity Pages they hot reload as well and automatically refresh from browser-link. If I edit literally anything on the Client side. It'll recompile, hot-reload, I get the checkbox in the browser, but the application does not change.

I have to stop, rebuild and start the application again running from the server project in this case for client-side changes to take effect.

Secondarily If I publish changes to the hosting server. None of the active clients get updated apps without doing a full browser history clean yes that's right a full browser history clean. On mobile devices that's a real PITA definitely cannot take this application I'm working on to a production environment.

I love Blazor so much though it's hard to be mad at the end of the day ;).

SteveSandersonMS commented 2 years ago

@pranavkm Since they aren't using runtime compilation, do you have any other suggestions on what might be wrong here, or do we need to investigate?

Aquaritek commented 2 years ago

@SteveSandersonMS I think this has something to do with the browser instance reloading a cached version of the application.

I have been working on this for several days and cannot get browsers (Edge, Chrome, Chromium, or Safari) to refresh the application on publish to my development server.

When you build and run from VS a completely cleaned instance of Edge or Chrome get's started that has no cached version of the application. I think this is where the issue actually lies. I do not understand the core architecture in that area though.

I do wonder though, if this has something to do with the application being setup as a PWA and the default behavior of a browser is to active any site changes after all iterations of that site have been terminated. Thoughts on this would be nice.

mkArtakMSFT commented 2 years ago

@SteveSandersonMS I think this has something to do with the browser instance reloading a cached version of the application.

I have been working on this for several days and cannot get browsers (Edge, Chrome, Chromium, or Safari) to refresh the application on publish to my development server.

When you build and run from VS a completely cleaned instance of Edge or Chrome get's started that has no cached version of the application. I think this is where the issue actually lies. I do not understand the core architecture in that area though.

I do wonder though, if this has something to do with the application being setup as a PWA and the default behavior of a browser is to active any site changes after all iterations of that site have been terminated. Thoughts on this would be nice.

Hi @Aquaritek. The issue you report seems different. Please file a separate issue so that we track it separately.

mkArtakMSFT commented 2 years ago

@HybridSolutions can you see any errors in the browser console? Also, please share any activity from the network tab that is initiated by aspnetcore-browser-refresh.js.

ghost commented 2 years ago

Hi @HybridSolutions. We have added the "Needs: Author Feedback" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

mkArtakMSFT commented 2 years ago

Also, a repro project (hosted as a public GitHub repo) would help.

HybridSolutions commented 2 years ago

@HybridSolutions can you see any errors in the browser console? Also, please share any activity from the network tab that is initiated by aspnetcore-browser-refresh.js.

This issue is easy to find in stackoverflow site. A lot of people having the same issue.

I can't make my project available for you to test because is proprietary but the issue is easily replicated.

  1. Make a new .NET 6 "ASP.NET Core Web App" with Razor pages using latest VS 2022 (17.0.2)
  2. Configure it in Program.cs to also support Blazor.
    // Add services to the container.
    builder.Services.AddServerSideBlazor(); // Add support for Blazor
    builder.Services.AddRazorPages();       // Add support for .Net Core Razor Pages

    and

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapRazorPages();

app.MapDefaultControllerRoute(); //Suppport .Net Core MVC
app.MapBlazorHub(); // Add the Blazor Hub endpoint
app.MapFallbackToPage("/_Host");
app.Run();
  1. Run it and try to change .chtml files. I have to refresh the browser to see changes although I can see the checkmark in the top left corner.
  2. Change a Blazor component. I can see changes immediately but only on the content of that component. All the remaining Razor page content does not update.

In Console I only get this during my above tests. No errors.

Debugging aspnetcore-browser-refresh.js, as soon as I save changes to a .cshtml file, the function aspnetCoreHotReloadApplied() gets hit but although I don't have any Blazor component in the page, the line window.Blazor is true, so location.reload(); is skipped and instead it always calls notifyHotReloadApplied();. That's the function that shows the checkmark svg. The browser reload function never gets called and for razor pages content, I guess location.reload(); must be called to see any changes.

Image of script debug

May this be the reason for not seeing changes in razor pages? Mixing Blazor with Razor pages makes all pages run as if it was a Blazor project so content does not update as would normally would.

pranavkm commented 2 years ago

@HybridSolutions thanks for the detailed writeup. Our current heuristic chooses to not refresh the browser for code changes if Blazor is running in the app. We had previously tried relying on the file that changed to make a determination but it gets tricky and inconsistent if there's more than one being updated as part of a hot reload update.

We're working on producing a write up for all these gotchas in our documentation, hopefully that helps here.

ghost commented 2 years ago

Thanks for contacting us.

We're moving this issue to the .NET 7 Planning milestone for future evaluation / consideration. We would like to keep this around to collect more feedback, which can help us with prioritizing this work. We will re-evaluate this issue, during our next planning meeting(s). If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

HybridSolutions commented 2 years ago

But will there be a solution in these cases?

pranavkm commented 2 years ago

@HybridSolutions for the immediate future we're going to rely on users having to manually refresh the browser in this particular case. For a longer term, we were looking at building more generalized rules about how to process changes to individual file types that can be shared by VS and dotnet-watch rather than baking in details about .cshtml, Blazor etc.

HybridSolutions commented 2 years ago

@HybridSolutions for the immediate future we're going to rely on users having to manually refresh the browser in this particular case. For a longer term, we were looking at building more generalized rules about how to process changes to individual file types that can be shared by VS and dotnet-watch rather than baking in details about .cshtml, Blazor etc.

That's ok for me. being able to see changes even by pressing F5 is great! .NET 6 and VS 2022 is turning into a wonderful development environment!

dotnetshadow commented 2 years ago

I had a similar issue and my .cshtml worked once I did the following:

<ItemGroup>
      <!-- extends watching group to include *.cshtml files -->
      <Watch Include="**\*.cshtml" Exclude="node_modules\**\*;**\*.js.map;obj\**\*;bin\**\*" />
  </ItemGroup>

I needed to do this from a converted project, when I create a new project it seems to work without the need to do the above. I wonder why the above is necessary?

HybridSolutions commented 2 years ago

I had a similar issue and my .cshtml worked once I did the following:

<ItemGroup>
    <!-- extends watching group to include *.cshtml files -->
    <Watch Include="**\*.cshtml" Exclude="node_modules\**\*;**\*.js.map;obj\**\*;bin\**\*" />
  </ItemGroup>

I needed to do this from a converted project, when I create a new project it seems to work without the need to do the above. I wonder why the above is necessary?

This does not work with the issue presented here since as I explained, the problem is on the script that does not invoke the refresh function location.reload(); when using Razor pages + Blazor in a project.

IndigoHealth commented 2 years ago

Not sure if this is off-topic. I submitted #39508 about this same issue with a vanilla ASP.Net Core MVC app. No Blazor involved.

Steps To Reproduce

Expected Behavior Welcome text changes

Actual Behavior Welcome text does not change

Other things I've tried

SteveSandersonMS commented 2 years ago

@sbsw I'm afraid hot reload requires .NET 6 (so, target net6.0).

programad commented 2 years ago

I have the same issue on my asp.net mvc core 5 app being migrated to asp.net core 6.0. (no blazor involved).

It just doesn't work.

I make the change to a cshtml file, nothing happens (no matter what hot reload button setting o do). When trying to refresh the page on the browser, get the following error: image

Edit: Found out that my issue seem to be related to the use of the ViewBag. Apparently, hot reload doesn't play well with dynamic and this fix is scheduled to .net 7 which comes out around november/22

alex-jitbit commented 2 years ago

I also have a .NET 5 app migrated to .NET 6 and .cshtml hot reload is not working neither for me, not for any of my coworkers even after refreshing the page in browser. I filed an issue in "Visual Studio Feedback" but no help from Microsoft.

UPD: The "visual studio feedback" website just closed my issue without providing any workaround.

Jbechler2 commented 2 years ago

I also have a .NET 5 app migrated to .NET 6 and .cshtml hot reload is not working neither for me, not for any of my coworkers even after refreshing the page in browser. I filed an issue in "Visual Studio Feedback" but no help from Microsoft.

UPD: The "visual studio feedback" website just closed my issue without providing any workaround.

I'm experiencing this as well. Just upgraded my project to from .NET 5 to .NET 6 and now any changes made to a .cshtml are not visible on the page until I stop and restart debugging.

Update: I was able to get this working by updating the Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation package to v6.0.5

ellinge commented 2 years ago

I had a similar issue and my .cshtml worked once I did the following:

<ItemGroup>
    <!-- extends watching group to include *.cshtml files -->
    <Watch Include="**\*.cshtml" Exclude="node_modules\**\*;**\*.js.map;obj\**\*;bin\**\*" />
  </ItemGroup>

I needed to do this from a converted project, when I create a new project it seems to work without the need to do the above. I wonder why the above is necessary?

Thank you! Hot reload would work once when editing a cshtml. After removing the same text that just was added (and the following changes), "No code changes found" was given as a status instead of "Code changes were applied successfully". A restart of the session was required to get it working again. No hints of cause in any of the debug outputs (is it possible to have a verbose output of Hot reload?). We use feature folders though and have a mix of Mvc and RazorPages (removing those would not fix the issue though). We removed Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation in the upgrade to .NET 6. Currently using VS2022 17.2.3.

Update: Seems to be a bit shaky still but much more stable at least

alex-jitbit commented 2 years ago

I had a similar issue and my .cshtml worked once I did the following:

<ItemGroup>
    <!-- extends watching group to include *.cshtml files -->
    <Watch Include="**\*.cshtml" Exclude="node_modules\**\*;**\*.js.map;obj\**\*;bin\**\*" />
  </ItemGroup>

Didn't work for me at all. Just as all the other workarounds. Hot reload is still not functioning in VS 2022 in my .NET 6 project converted from .NET 5. Works only in "Start without debugging". Does not work in Debug" mode. Even when I click the hot reload button and refresh the page manually, changes are not there

dotnetshadow commented 2 years ago

Just a warning about an unintended consequence of using this snippet. When you you add a new .chtml file to your solution the build action defaults to None. Not sure why it's doing that.

 <Watch Include="**\*.cshtml" Exclude="node_modules\**\*;**\*.js.map;obj\**\*;bin\**\*" /> 

Someone else had the exact same problem: https://stackoverflow.com/questions/72909569/in-net-6-mvc-view-is-404-not-found-unless-i-manually-change-the-file-type-to

lwpinion commented 2 years ago

Are there any updates on this? We're encountering this issue on a project that we're migrating to .NET 6. I've double-checked and our dependencies are on .NET 6 as well.

I don't know if this makes a difference, but ours is not a Blazor project. Just an MVC project with Razor templates.

Just a warning about an unintended consequence of using this snippet. When you you add a new .chtml file to your solution the build action defaults to None. Not sure why it's doing that.

 <Watch Include="**\*.cshtml" Exclude="node_modules\**\*;**\*.js.map;obj\**\*;bin\**\*" /> 

Someone else had the exact same problem: https://stackoverflow.com/questions/72909569/in-net-6-mvc-view-is-404-not-found-unless-i-manually-change-the-file-type-to

@dotnetshadow Aside from the unintended consequence, is this still a viable workaround?

alex-jitbit commented 2 years ago

This is what helped me resolve the issue: https://github.com/dotnet/aspnetcore/issues/43910

mkArtakMSFT commented 2 years ago

@HybridSolutions for the immediate future we're going to rely on users having to manually refresh the browser in this particular case. For a longer term, we were looking at building more generalized rules about how to process changes to individual file types that can be shared by VS and dotnet-watch rather than baking in details about .cshtml, Blazor etc.

@BillHiebert , @tmat do you guys know who would be the owner of this action? Where does this logic lie in today?

tmat commented 2 years ago

@mkArtakMSFT I think we have 3 kinds of files: 1) .cs/.vb files 2) files that Razor SDK uses as inputs to the source generator (.razor, .cshtml) 3) .css and other content

[1] and [2] are handled the same way - it all goes through Roslyn. [3] are handled separately.

tmat commented 1 year ago

I validated that repro https://github.com/dotnet/aspnetcore/issues/38809#issuecomment-988195666 works without issues when using .NET 6.0.406 and 7.0.200.

Re https://github.com/dotnet/aspnetcore/issues/38809#issuecomment-1012738824: .NET 5 does not support Hot Reload.

I also tried creating .NET 5 Web App and changing TFM to net6.0. Hot Reload works.

If there is any scenario I missed that still does not work with the latest .NET 7 SDK, please file an issue with detailed repro steps.

LongBrandon commented 1 year ago

I know this issue is closed. But I'm leaving this here in case it helps someone out. In my case I had the following in my Blazor Server project file. I don't remember making this change but perhaps I did when migrating from dotnet 5 to dotnet 6.

  <PropertyGroup>
    <UseRazorSourceGenerator>false</UseRazorSourceGenerator>
  </PropertyGroup>

If I remove this property from the .proj file my hot reload now works.