Localhost not found after migrating application from .net 5 to .net 6 - asp.net-core

I am unable to run my web application project in IIS Express after migrating from .net 5 to .net 6. I get an error stating that "the localhost page can't be found."
From what I've been able to learn, I have gone through the proper steps to migrate between target frameworks. I have changed the target framework to .net 6 in application properties, and I have updated all affected NuGet packages using the NuGet Pkg Manager. No errors are shown when I build the project, and I have ensured Visual Studio is updated to the latest version, 17.2.5 as of this writing.
The IIS Settings in my launchsettings.json file are as follows:
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:35317",
"sslPort": 44352
}
}
and I do have an Index view return in my home controller. Yet I still get the error that
No webpage was found for the web address: https://localhost:44352/
when I run the application.
I am retaining the "old" hosting model of Startup.cs and Program.cs from the .Net 5 build to save time, as I understand per Microsoft that this is acceptable. No changes have been made to the code in either of those files.
What am I missing?
EDIT: My Program.cs code is below, by request of #adrianMoskal
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
EDIT 2:
Per #adrianMoskal, I updated my Program.cs file to .NET 6 standard. It now looks like this:
var builder = WebApplication.CreateBuilder(args);
// Add DB Contexts and Services here
// Add services to the container.
builder.Services.AddControllersWithViews();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
Unfortunately, the error persists.

I created a new project to migrate from .net 5 to .net 6, but no problem, it works fine, I will show you the complete steps:
.csproj:
change Version like below:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<!--<TargetFramework>net5.0</TargetFramework>-->
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>_2022070802</RootNamespace>
<CopyRefAssembliesToPublishDirectory>false</CopyRefAssembliesToPublishDirectory>
</PropertyGroup>
<ItemGroup>
<!--<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="5.0.16" />-->
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="6.0.1" />
</ItemGroup>
</Project>
Then I delete Startup.cs and change Program.cs:
var builder = WebApplication.CreateBuilder(args);
// Add DB Contexts and Services here
// Add services to the container.
builder.Services.AddControllersWithViews();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
More detail information, see this link.
You can create a new empty project to migrate from .net 5 to .net 6 and see if the problem still exists.I think this may be the problem caused by some of your configuration, maybe you can check whether your path is correct?

Chen's answer is the correct migration step.
I tried to reproduce your issue. When I comment Index page method in HomeController. And I face the same issue.
So you probably deleted your "Index" action in HomeController.

The answer appears to be "screw you, start over."
I've tried copying my project code to a new .net 6 project -- that is, copying all the views, controllers, and whatnot to the new project and updating the new Program.cs file accordingly -- and I still got the same error. I then tried converting a different .net 5 project to .net 6, and got the same error again. So apparently, converting just doesn't work.
So be it. I quit. I've got too much else to do to worry about this. Thanks to those who responded to this post for trying to help resolve it, anyway.

Related

swagger/index.html shows a blank page (asp.net core)

I am writing a web api in ASP.NET CORE for the data models Package and Content. They are originally from MSSQL so I connected to the db server successfully. After writing http requests in the controllers, when I ran the project to test, it takes me to swagger/index.html that shows a blank page, I have no idea why.
Here is my program.cs
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
//OperationsContext is a db context that has both content and package dbcontext
builder.Services.AddDbContext<OperationsContext>(x => x.UseSqlServer(connectionString));
/*builder.Services.AddMvc();
builder.Services.AddHttpContextAccessor();*/
builder.Services.AddScoped<IContentRepository, ContentRepository>();
builder.Services.AddScoped<IPackageRepository, PackageRepository>();
var app = builder.Build();
// Configure the HTTP request pipeline.
app.UseSwagger();
app.UseSwaggerUI(c =>
{
if (app.Environment.IsDevelopment() || app.Environment.IsProduction())
{
c.SwaggerEndpoint("/swagger/Package/swagger.json", "Package v1");
}
else
{
// To deploy on IIS
c.SwaggerEndpoint("/swagger/Package/swagger.json", "Package v1");
}
});
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
I am assuming it's the program.cs, but there are no issues when I ran it. Does anyone know why?
Swagger UI does not support Internet Explorer. Use Chrome, Firefox, Safari, or Edge instead.

Localization not working in .NET6 Razor Pages project

I was trying to get localization to work in my 'real' project, but was not able to do so. So I created a new stock .NET6 Razor Pages project to test localization in a fresh environment. However I am not quite able to do that there as well. At this point I have read about 6 articles, watched 2 tutorials and read the official documentation which says that it is up to date with .NET6, but I'm not sure about that (partly because the examples use old syntax, i.e. not things that came with .NET6). Every single one of those resources more or less did/said the same things, which is what I have right now, but it just doesn't work.
This is my Program.cs file:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
//builder.Services.AddRazorPages(); builder.Services.AddMvc().AddDataAnnotationsLocalization();
builder.Services.AddRazorPages().AddDataAnnotationsLocalization();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
var supportedCultures = new[] { "en" };
var localizationOptions = new RequestLocalizationOptions().SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
app.UseRequestLocalization(localizationOptions);
app.UseAuthorization();
app.MapRazorPages();
app.Run();
I have tested the "things I'll mention bellow" with ...AddRazorPages().AddData... and (AddMvc().AddData... with ...AddRazorPages();) as well. That's why one of those lines is commented.
The way I am testing the localization is just with an OnGet call on the Index page, and restarting the (local) server after every change just to not miss some dumb thing. On the OnGet, I just log the value to the console. But I'm always getting the key. Here is the IndexModel class:
public class IndexModel : PageModel
{
private readonly IStringLocalizer<IndexModel> _localizer;
public IndexModel(IStringLocalizer<IndexModel> localizer)
{
_localizer = localizer;
}
public void OnGet()
{
Console.WriteLine(_localizer["Test"].Value);
}
}
This is how my (relevant) folder structure looks like in the project's directory:
And finally the resx file:
Things I have tested are the .resx file names and the 2 possible locations. I am sure that both are correct, because when both files were active (neither had the .Dup (for duplicate) extension) at the end, I got an error from the compiler that multiple resources point to the same location or something like that.
The names I have tested are the following:
IndexModel.en.resx
Index.en.resx
IndexModel.cshtml.cs.en.resx
Index.cshtml.cs.en.resx
IndexModel.cs.en.resx
Index.cs.en.resx

Blazor Server Side Localization without cookie

So Im trying to add Localization without a cookie to my Blazor Server Side project.
In the documentaition https://learn.microsoft.com/en-us/aspnet/core/blazor/globalization-localization?view=aspnetcore-5.0#provide-ui-to-choose-the-culture it says:
Use of a cookie ensures that the WebSocket connection can correctly propagate the culture. If localization schemes are based on the URL path or query string, the scheme might not be able to work with WebSockets, thus fail to persist the culture. Therefore, use of a localization culture cookie is the recommended approach.
So I know its not recommended, but I would like it to be path-based anyway if possible. Can it be done with the standard services.AddLocalization(); and IStringLocalizer, or do I have to build a custom one?
For Localization, I prefer a direct, clear, and readable link that contains the language's first 2 letters (like: mysite.com/en/mypage ), which allows having the correct link using exactly the language needed.
The only solution I found that works perfectly with Blazor Server without the need for Cookies was using the package "BlazorServerUrlRequestCultureProvider" created by "Pier-Luc Bonneville"; it is effortless to use and gives excellent results.
Usage:
Install the package BlazorServerUrlRequestCultureProvider (worked perfectly for me with .Net 5.0):
Install-Package BlazorServerUrlRequestCultureProvider -Version 1.0.0
Startup.cs:
using BlazorServerUrlRequestCultureProvider;
// ...
//------------------------------
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// ...
// Set the Resources folder name:
services.AddLocalization(options => options.ResourcesPath = "Resources");
// ...
}
}
//------------------------------
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
}
app.UseHttpsRedirection();
app.UseStaticFiles();
#region Localization
var supportedCultures = new[]
{
new CultureInfo("en"),
new CultureInfo("ar"),
};
var options = new RequestLocalizationOptions
{
// Select a default language:
DefaultRequestCulture = new RequestCulture("en"),
// For Numbers, Dates, etc:
SupportedCultures = supportedCultures,
// For strings that we have localized in .resx files:
SupportedUICultures = supportedCultures
};
app.UseUrlRequestLocalization(options);
#endregion
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
app.UseRequestLocalization();
}
That was just all you need! No Cookies nor Controllers!
Now use StringLocalizer as usual (in my case, the resource files names were App.resx and App.ar.resx inside the Resource folder):
MyPage.razor:
#page "/ar/MyPage"
#page "/en/MyPage"
#inject IStringLocalizer<App> localizer
<h1>#localizer["My Translated Text Here !"]</h1>
All Thanks & Credits goes to "Pier-Luc Bonneville" for his wonderful work. Project Website , NuGet .
--
Bonus:
To make your life much easier, use the tool ResXManager to easily manage and translate resource files, it's a free and great tool, and it will save you a lot of time.

ASP.Net Core spa pre-rendering with angular universal works locally but not on server

I'm trying to set up angular universal on angular7 with asp.net core 2.1. The prerendering works perfectly on a local build but does not add code to the page source on a server in production with no errors or logs.
Due to the lack of logs I suspect this is because the server module is not loaded/ started but I have no idea why. Is this something that should be added into the web config?
I am using a windows shared plesk server which supports node.js and IIS Node. Here is a snippet from my Startup.cs
app.UseSpa(spa =>
{
spa.Options.StartupTimeout = new System.TimeSpan(0, 0, 1000);
spa.Options.SourcePath = "ClientApp";
spa.UseSpaPrerendering(options =>
{
options.BootModulePath = $"{spa.Options.SourcePath}/dist-server/main.js";
options.BootModuleBuilder = env.IsDevelopment() ? new
AngularCliBuilder(npmScript: "build:ssr") : null;
options.ExcludeUrls = new[] { "/sockjs-node" };
});
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
I eventually realised I had the line app.UseStaticFiles(); as well as app.UseSpaStaticFiles in Startup.cs. Removing app.UseStaticFiles(); solved this issue. However, I am still not sure why this wasn't causing issues on a local build.
I believe you are misusing the prerendering middleware.
About prerendering: Represents the ability to build a Single Page Application (SPA) on demand so that it can be prerendered. This is only intended to be used at development time. In production, a SPA should already have been built during publishing.
You should hide that piece of code behind:
env.IsDevelopment()
Read more here

How do I get an Angular TS file to compile and update on save in a .Net Core project?

So I was watching a channel 9 video on Angular CLI with .Net Core here: https://channel9.msdn.com/Shows/Visual-Studio-Toolbox/Angular-and-NET-Core
At position 8:15 he demos auto-syncing where updating a .ts file in the Angular CLI folder compiled on save, then later caused the view to update. I tried this an it does not update at all (unless I refresh the whole page).
I also noticed that the template does not work out of the box (big surprise). I managed to update it to the newer Angular version (and ran into an error where the template had incorrectly created "start": "ng serve --extract-css", to package.json where --extract-css is invalid and had to remove it). I also assumed that Visual Studio (2017) would compile Angular on its own, but it did not, so I added this to the project file:
<Target Name="NgDebug" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' ">
<!--Run Angular build in debug mode (NOTE: does not support symbolic links nor junction points)-->
<Message Importance="high" Text="Building the Angular code in debug (dev) mode ..." />
<Exec WorkingDirectory="$(SpaRoot)" Command="ng build" />
</Target>
<Target Name="NgRelease" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Release' ">
<!--Run Angular build in prod mode (NOTE: does not support symbolic links nor junction points)-->
<Message Importance="high" Text="Building the Angular code in release (prod) mode ..." />
<Exec WorkingDirectory="$(SpaRoot)" Command="ng build --prod" />
</Target>
Two questions here:
Is this sync feature expected to work today? Is there a configuration required?
Am I expected to setup the ng build step myself, or is there a different method I should be using for the ASP.Net Core (with Angular CLI) template?
Here is the app.UseSpa code:
app.UseSpa(spa =>
{
// To learn more about options for serving an Angular SPA from ASP.NET Core,
// see https://go.microsoft.com/fwlink/?linkid=864501
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
So it appears the correct terminology is "Hot Module Replacement" (MHR - AKA "Live Reloading", or "Hot Updates/Reloading"). Following this answer got me part way there:
https://stackoverflow.com/a/50934814/1236397
The part missing was found here: https://github.com/aspnet/JavaScriptServices/issues/1654#issuecomment-430053872
Both of these links seem to suggest that the template Visual Studio creates is ready for production and not development. The two issues are:
The ClientApp\dist folder may get created at some point if you build outside Visual Studio. The existence of the manually created dist folder will break the live reloading. This folder must be deleted entirely.
The VS ASP.Net Core Angular CLI template is ready to serve static files in production mode. The template creator failed to wrap sections to prevent loading in dev mode.
For #2 change these lines:
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
...
public IConfiguration Configuration { get; }
...
public void ConfigureServices(IServiceCollection services)
{
...
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
...
}
...
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
app.UseSpaStaticFiles();
...
}
to this:
public Startup(IHostingEnvironment env, IConfiguration configuration)
{
HostingEnvironment = env;
Configuration = configuration;
}
...
public IHostingEnvironment HostingEnvironment { get; private set; }
public IConfiguration Configuration { get; }
...
public void ConfigureServices(IServiceCollection services)
{
...
if (HostingEnvironment.IsProduction())
{
// In production, the Angular files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
}
...
}
...
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
if (env.IsProduction())
{
app.UseSpaStaticFiles();
}
...
}
However, at this point the pages refresh in full. This is because HMR is not enabled by default. You'll have to follow the proper documentation here:
https://github.com/angular/angular-cli/wiki/stories-configure-hmr
If the link ever goes down, simply search for the documentation using the query configure HMR for angular CLI.
Tip: If you need IE9-11 support, take a look at the polyfills.ts file, and ignore the import 'classlist.js' line, unless you need it (otherwise run npm install --save classlist.js).