Replacing UseMvc in .Net Core 3.0 - c#

I'm trying to figure out how to properly replace app.UseMvc() code that use to be part .net core 2.2. The examples go so far as to tell me what are all the codes I can call but I'm not yet understanding which should I call. For example for my MVC Web Application I have the following:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseStatusCodePagesWithReExecute("/Error/Index");
app.UseMiddleware<ExceptionHandler>();
app.UseStaticFiles(new StaticFileOptions()
{
OnPrepareResponse = (context) =>
{
context.Context.Response.GetTypedHeaders()
.CacheControl = new CacheControlHeaderValue
{
MaxAge = TimeSpan.FromDays(30)
};
}
});
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
});
}
Before I would provide my routing inside the UseMvc() options. However now it seems I have to provide it inside MapControllerRoute But the examples always seem to also call MapRazorPages(). Do I need to call both or am I suppose to call just one? What is the actual difference between the two and how do I setup a default controller and a default action?

This is documented in the Migrate from ASP.NET Core 2.2 to 3.0 article. Assuming you want an MVC application.
The following example adds support for controllers, API-related
features, and views, but not pages.
services
// more specific than AddMvc()
.AddControllersWithViews()
.SetCompatibilityVersion(CompatibilityVersion.Version_3_0)
And in Configure:
public void Configure(IApplicationBuilder app)
{
app.UseStaticFiles();
app.UseRouting();
// The equivalent of 'app.UseMvcWithDefaultRoute()'
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
// Which is the same as the template
endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
});
}
For the order of use statemtents check the documentation.

The easiest way to fix it...
Build a new project targeting the .NET Core that you need and just copy the new Configure method and paste into your project that you are migrating to...
In this example...
Here are the old code lines:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
}
And here are the new code lines:
// This method gets called by the runtime. Use this method to configure
the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}

Related

HTTP Error 500.30 - ANCM In-Process Start Failure .NET Core

I am using .NET Core 3.0 and suddenly I am getting error below, yes it was working fine last week:-
Nonetheless something has changed and I can't workout what - seems to be related to a directory being wrong.
I have deleted the .vs hoping it would work after it is regenerated...
I have followed below links but to no avail...
HTTP Error 500.30 - ANCM In-Process Start Failure
Reading and using appsettings.json in Program.cs?
https://forums.asp.net/t/2159371.aspx?Application+LM+W3SVC+10+ROOT+failed+to+start+process+ErrorCode+0x80070005+
Dotnet Core Multiple Startup Classes with In-Process Hosting
The Event Viewer shows:-
Adding StartUp.cs
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddAuthorization(options =>
{
options.AddPolicy("ADGroup", policy =>
policy.Requirements.Add(new UserHelper.CheckAdGroupRequirement(Configuration["SecuritySettings:ADGroup"])));
});
services.AddSingleton<IAuthorizationHandler, UserHelper.CheckAdGroupHandler>();
services.AddHttpContextAccessor();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public static void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error/{0}");
// 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.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
A nudge in the right direction would be highly appreciated....

IApplicaionBuilder dos not contain a definition MapSignalR(). app.MapSignalR() not workin on ASP.NET CORE

I want to incorporate SignalR on my project but I can't I have an error when I add the line app.MapSignalR() in the Startup class. Here is the StartUp class:
public class Startup
{
public Startup(IConfiguration configuration{...}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{...}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseAuthentication();
app.MapSignalR(); // ERROR - IApplicaionBuilder dos not contain a definition MapSignalR() and the best extension method overload ' OwinExtensios.MapSignalR(IAppBuilder)' requires a receiver of type 'IAppBuilder'
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
I already added 'using Owin;' and it still doesn't work. What should I do?
Use like this. This is for .net core 3.0+
public void ConfigureServices(IServiceCollection services)
{
services.AddSignalR();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/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.UseEndpoints(endpoints =>
{
endpoints.MapHub<ChatHub>("/chatHub");
});
}
Read more : https://learn.microsoft.com/en-us/aspnet/core/tutorials/signalr?view=aspnetcore-3.1&tabs=visual-studio
Use below if .net core 2.2
app.UseSignalR(routes =>
{
routes.MapHub<ChatHub>("/chatHub");
});
instead of
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<ChatHub>("/chatHub");
});

CORS Headers missing from basic API response apnetnet core 3.0

I have just created a default dotnet core 3.0 API project with the basic weather forecast API. I wanted to get CORS working before I did anything else with the project.
In startup i have the following code....
private readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy(MyAllowSpecificOrigins,
builder =>
{
builder.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod();
});
});
services.AddControllers();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseCors(MyAllowSpecificOrigins);
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
As you can see, I am not doing anything special or seemingly incorrect. This is directly from the MSDN documentation....
https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-3.0
The problem is that when sending requests through both the browser and postman, There are none of the expected headers in the given responses.
I have googled the crap out of this and have not got anywhere. Am i missing something? could it be environmental? has it changed from a previous version of core?

Does any extra configuration need to be done for IActionContextAccessor with ASP.NET Core 3.0?

So, I am trying to migrate my ASP.NET Core project to 3.0, and am having some breaking changes. I am trying to use OpenID Connect with AWS Cognito to authenticate users to the web application. Worked fine in my 2.2 project, but no longer works with 3.0 (preview 9).
This is the error I receive:
An unhandled exception has occurred while executing the request.
System.ArgumentNullException: context (Parameter 'Value cannot be null or empty.')
at Microsoft.AspNetCore.Mvc.Routing.UrlHelperFactory.GetUrlHelper(ActionContext context)
It seems as though my IActionContextAccessor is now null when trying set this up.
IActionContextAccessor is injected in an AuthenticationBuilder function.
I am not sure what might be the issue.
In my startup.cs in the Configure function I have the following:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UsePathBase("/");
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/error/500/");
}
app.UseStatusCodePagesWithRedirects("/error/{0}/");
app.UseAuthentication();
if (env.IsProduction())
{
app.Use((context, next) =>
{
// https://github.com/aspnet/Security/issues/757
context.Request.Scheme = "https";
return next();
});
}
app.UseStaticFiles();
app.UseRouting();
//app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Endpoints}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
}
I have also included this in my .csproj:
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="3.0.0-preview9.19424.4" />
Is there some weird thing I'm now missing?

Using 'UseMvc' to configure MVC is not supported while using Endpoint Routing

I had an Asp.Net core 2.2 project.
Recently, I changed the version from .net core 2.2 to .net core 3.0 Preview 8. After this change I see this warning message:
using 'UseMvc' to configure MVC is not supported while using Endpoint
Routing. To continue using 'UseMvc', please set
'MvcOptions.EnableEndpointRouting = false' inside 'ConfigureServices'.
I understand that by setting EnableEndpointRouting to false I can solve the issue, but I need to know what is the proper way to solve it and why Endpoint Routing does not need UseMvc() function.
I found the solution, in the following official documentation "Migrate from ASP.NET Core 2.2 to 3.0":
There are 3 approaches:
Replace UseMvc or UseSignalR with UseEndpoints.
In my case, the result looked like that
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
//Old Way
services.AddMvc();
// New Ways
//services.AddRazorPages();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseStaticFiles();
app.UseRouting();
app.UseCors();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}");
});
}
}
OR
2. Use AddControllers() and UseEndpoints()
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseStaticFiles();
app.UseRouting();
app.UseCors();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
OR
3. Disable endpoint Routing. As the exception message suggests and as mentioned in the following section of documentation: use mvcwithout endpoint routing
services.AddMvc(options => options.EnableEndpointRouting = false);
//OR
services.AddControllers(options => options.EnableEndpointRouting = false);
This worked for me (add in Startup.cs > ConfigureServices method):
services.AddMvc(option => option.EnableEndpointRouting = false)
but I need to know what is the proper way to solve it
In general, you should use EnableEndpointRouting instead of UseMvc, and you could refer Update routing startup code for detail steps to enable EnableEndpointRouting.
why Endpoint Routing does not need UseMvc() function.
For UseMvc, it uses the IRouter-based logic and EnableEndpointRouting uses endpoint-based logic. They are following different logic which could be found below:
if (options.Value.EnableEndpointRouting)
{
var mvcEndpointDataSource = app.ApplicationServices
.GetRequiredService<IEnumerable<EndpointDataSource>>()
.OfType<MvcEndpointDataSource>()
.First();
var parameterPolicyFactory = app.ApplicationServices
.GetRequiredService<ParameterPolicyFactory>();
var endpointRouteBuilder = new EndpointRouteBuilder(app);
configureRoutes(endpointRouteBuilder);
foreach (var router in endpointRouteBuilder.Routes)
{
// Only accept Microsoft.AspNetCore.Routing.Route when converting to endpoint
// Sub-types could have additional customization that we can't knowingly convert
if (router is Route route && router.GetType() == typeof(Route))
{
var endpointInfo = new MvcEndpointInfo(
route.Name,
route.RouteTemplate,
route.Defaults,
route.Constraints.ToDictionary(kvp => kvp.Key, kvp => (object)kvp.Value),
route.DataTokens,
parameterPolicyFactory);
mvcEndpointDataSource.ConventionalEndpointInfos.Add(endpointInfo);
}
else
{
throw new InvalidOperationException($"Cannot use '{router.GetType().FullName}' with Endpoint Routing.");
}
}
if (!app.Properties.TryGetValue(EndpointRoutingRegisteredKey, out _))
{
// Matching middleware has not been registered yet
// For back-compat register middleware so an endpoint is matched and then immediately used
app.UseEndpointRouting();
}
return app.UseEndpoint();
}
else
{
var routes = new RouteBuilder(app)
{
DefaultHandler = app.ApplicationServices.GetRequiredService<MvcRouteHandler>(),
};
configureRoutes(routes);
routes.Routes.Insert(0, AttributeRouting.CreateAttributeMegaRoute(app.ApplicationServices));
return app.UseRouter(routes.Build());
}
For EnableEndpointRouting, it uses EndpointMiddleware to route the request to the endpoints.
The issue I found to be due to updates on the .NET Core framework. The latest .NET Core 3.0 released version requires explicit opt-in for using MVC.
This issue is most visible when one tries to migrate from older .NET Core(2.2 or preview 3.0 version) to .NET Core 3.0
If migrating from 2.2 to 3.0, please use the below code to fix the issue.
services.AddMvc(options => options.EnableEndpointRouting = false);
If using .NET Core 3.0 template,
services.AddControllers(options => options.EnableEndpointRouting = false);
ConfigServices method after fix as below,
Thank You
Endpoint Routing is disabled by default on ASP.NET 5.0
Just configure as in Startup
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options => options.EnableEndpointRouting = false);
}
This worked for me
You can use :
in ConfigureServices method:
services.AddControllersWithViews();
And for Configure method:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
//Old Way
services.AddMvc();
// New Ways
//services.AddRazorPages();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseStaticFiles();
app.UseRouting();
app.UseCors();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}");
});
}
}
This works also in .Net Core 5
For DotNet Core 3.1
Use below
File : Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseHttpsRedirection();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
-> In ConfigureServices method - Startup.cs
//*****REGISTER Routing Service*****
services.AddMvc();
services.AddControllers(options => options.EnableEndpointRouting = false);
-> In Configure Method - Startup.cs
//*****USE Routing*****
app.UseMvc(Route =>{
Route.MapRoute(
name:"default",
template: "{Controller=Name}/{action=Name}/{id?}"
);
});
This worked for me
services.AddMvc(options => options.EnableEndpointRouting = false); or
OR
services.AddControllers(options => options.EnableEndpointRouting = false);
Use Below Code
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
endpoints.MapGet("/", async context =>
{
await context.Response.WriteAsync("Hello World!");
});
});

Categories