Not able to route to API in Blazor Server app - c#

I’m brand new to Blazor and I’m trying to learn by converting an old website/web API project into a .Net 6 Blazor Server app where I plan to have both the UI and the API in the same application. I created a Controllers folder and added a controller called ApiController. I also set up Entity Framework and created my Entity classes for my SQL database tables. I’ve added the first HTTPGET route and tried hitting it through Postman to see if it will work. However, I keep getting a message that the page can not be found.
I thinking I need to add something to the Program.cs to let it know that I’m wanting to use APIs and Routing but, in my research, I’m not finding what I’m missing or what needs to be added. Most examples want to use a WASM project which probably has the API and Routing information built in.
This is the URL I'm trying to hit.
https://localhost:7168/api/usersadmin/GetAppNames
ApiController.cs
using Microsoft.AspNetCore.Mvc;
using UsersAdmin_AS.Data;
namespace UsersAdmin_AS.Controllers
{
[Route("api/UsersAdmin/[action]")]
[ApiController]
public class ApiController : ControllerBase
{
[HttpGet]
[Route("GetAppNames")]
public List<string> GetAppNames()
{
//logger.Info("GetAppNames");
List<string> listAppNames = new List<string>();
try
{
var dataManager = new DataManager();
listAppNames = dataManager.GetAppNames();
}
catch (Exception ex)
{
//logger.Error("ERROR: {0} | {1} | {2}", ex.Message, ex.StackTrace, ex.InnerException);
throw;
}
return listAppNames;
}
}
Program.cs
using UsersAdmin_AS.Data;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<WeatherForecastService>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
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.MapBlazorHub();
app.MapFallbackToPage("/_Host");
app.Run();

Replace [Route("api/UsersAdmin/[action]")] with [Route("api/UsersAdmin/[controller]")]
and comment out [Route("GetAppNames")] in your controller.. Your swagger should show GetAppNames endpoint

I found this post and it fixed my issue.
https://stackoverflow.com/questions/70583469/host-web-api-in-blazor-server-application
This is the route I used at the top of the controller.
[Route("api/UsersAdmin/")]
I used this as my specific route.
[HttpGet]
[Route("GetAppNames")]
I added the builder.Services.AddControllers(), commented out the app.MapBlazorHub() and app.MapFallbackToPage("/_Host"). I then added the app.UseEndpoints() function.
Here is my updated Program.cs file.
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using UsersAdmin_AS.Data;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddControllers();
builder.Services.AddSingleton<WeatherForecastService>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
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.MapBlazorHub();
//app.MapFallbackToPage("/_Host");
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapBlazorHub();
endpoints.MapRazorPages();
endpoints.MapFallbackToPage("/_Host");
});
app.Run();

Related

.NET Identity not locking down static files after logging out

I am building a .NET Core 3.1 Web Application using .NET Identity to secure some static files (these are documentation files generated automatically that I do not want general users to be able to see). The application also uses MVC to serve some administration pages.
Things appear to work OK (if a new visitor to the site tries to go to the static pages, they get redirected to the 'Access Denied' page). If one logs in (and has the 'Admin' role set in the AspNet database), one can then see these files.
However, after such a user logs out, one can still get to the protected static files (although one can no longer get to the Admin pages served using MVC). Here is how the system is set up in the Startup.cs file:
using CoreMVC.Data;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Hosting;
using System.IO;
namespace CoreMVC
{
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.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
/*
services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
*/
// This gets the [Authorize(Roles = "Admin")] decoration working. N.B. reset RequireConfirmedAccount to false
services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = false)
.AddRoles<IdentityRole>()
.AddRoleManager<RoleManager<IdentityRole>>()
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddControllersWithViews();
services.AddRazorPages();
// Try putting the fallback authorization policy here
services.AddAuthorization(options =>
{
options.FallbackPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.RequireRole("Admin")
.Build();
});
}
// 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.UseDatabaseErrorPage();
}
else
{
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();
// Keep this in (otherwise we lose access to required resources)
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
// New mapping for static files - Seems OK to call UseStaticFiles twice!
// Note: moved this after UseAuthentication and UseAuthorization
// Try <host>/Documents/index.html
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.ContentRootPath, "Documents")),
RequestPath = "/Documents"
});
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
}
}
}
Note that the protection for the static files is provided by the fallback policy set up by the call to services.AddAuthorization in the ConfigureServices method, so this is distinct from the methods used to secure the pages served using MVC. I guess the problem is here somewhere.
I have tried deleting all Cookies using the browser dev tools but to no effect. Cookies on the system whilst logged in are:
.AspNetCore.Identity.Application
ARRAffinitySameSite
.AspNetCore.Antiforgery.9fXoN5jHCXs
ARRAffinity
After logging out, the .AspNetCore.Identity.Application cookie disappears. There do not seem to be any session or local variables stored.
Can anyone explain why this access is still being allowed and how to prevent it? As mentioned above, I suspect it is something to do with how the fallback policy is applied but I do not understand the details.
Update: On further investigation it seems that access to the static pages is only granted on the pages visited whilst logged in. This suggests that the server is maintaining some kind of list - an IIS issue maybe?
Further update: Thanks to the suggestion below, I now realise that this is due to browser caching, so not really an issue. I have now tried sticking
<meta http-equiv="Cache-Control" content="private, no-store" />
into the head section of the HTML pages and this seems to have worked.

.NET + Angular Template API Controller Route not working (404)

When I used This Template:
Template
for an Angular Frontend .NET Backend. But when I created an API Controller like this in the Controller Directory:
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace API.Controllers
{
[Route("[controller]")]
[ApiController]
public class TestController : ControllerBase
{
[HttpGet]
public int Get()
{
return 0;
}
}
}
I always get 404 Not Found in Postman with query "https://localhost:44490/Test" even though the "WeatherForecastController" template that was already in the Project works fine.
I tried the TestController in another Template that is just the .NET Backend and it works fine, I get a normal 200 back...
I also tried a 1 to 1 copy of the WeatherForecastController the Template came with but that also did not Work, I think the Program does not even get to the Controller so I guess there is something wrong with the routing setup. Im new to .Net so I might just have overseen something.
Any help is greatly appreciated.
This is the Program.cs that came with the Project:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
// 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.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
app.MapFallbackToFile("index.html");
app.Run();

How to create Startup class in ASP.NET Core 6 MVC

I am new and am studying ASP.NET Core 6 MVC. I am stuck in this error when building a Startup class like in my tutorial.
This is my Program.cs class:
var builder = WebApplication.CreateBuilder(args);
// 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();
Startup.cs class:
using Microsoft.Extensions.FileProviders;
using System;
using System.Collections.Generic;
namespace HCMUE_ASPCore_Lab02
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IFileProvider>
(
new PhysicalFileProvider
(
Path.Combine(Directory.GetCurrentDirectory(), "wwwroot")
)
);
services.AddMvc();
}
}
}
After reading many posts, I know that ASP.NET Core 6's Program and Startup have changed and my tutorial is old now. But I don't know how to update my Program and Startup to fit with ASP.NET Core 6.
Please help me. Any help would be appreciated.
Thank you for reading.
The error message is saying that your application is trying to create an instance of FileUploadController but it doesn't know how to create an instance of IFileProvider to pass into the constructor.
This is a typical dependency injection error, You can register it in this code:
builder.Services.AddSingleton<IFileProvider>(new PhysicalFileProvider
(
Path.Combine(Directory.GetCurrentDirectory(), "wwwroot")
));
You can follow this Docs to learn about Dependency injection and other fundamentals in .Net 6.
If you are not comfortable with the new changes in .Net6, you can add the Startup class according to this article.
You want to ensure that both the static file middleware, and any services that inject your file provider, end up using the same instance.
var provider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), "wwwroot")
);
builder.Services.AddSingleton<IFileProvider>(provider);
...
app.UseStaticFiles(
new StaticFileOptions{
FileProvider = provider
});
But if you don't really need a different file provider, you can instead inject IWebHostEnvironment into your controller and reuse the default .WebRootFileProvider.

This localhost page can’t be found Asp.Net 6.02

Db Configuration
Program.cs
using FirstApp.DataAccessLayer.Infrastructure.IRepository;
using FirstApp.DataAccessLayer.Infrastructure.Repository;
using FirstApp.DataAccessLayer;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Identity;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
// Add service to the razor pages
builder.Services.AddRazorPages();
//Add Service to the Repository
builder.Services.AddScoped<IUnitOfWork, UnitOfWork>();
// Register Context File
builder.Services.AddDbContext<ApplicationDbContext>(options =>
{
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"));
});
// Idenitity Service
builder.Services.AddDefaultIdentity<IdentityUser>
().AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddControllersWithViews().AddNewtonsoftJson(options =>
{
options.SerializerSettings.ReferenceLoopHandling =
Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});
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.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.MapControllerRoute(
name: "default",
//pattern: "{controller=Home}/{action=Index}/{id?}");
pattern: "{area=Clint}/{controller=Home}/{action=Index}/{id?}");
app.Run();
but did not work show the error i can't understand
this error show
error show
but did not work show the error i can't understand
this error show
but did not work show the error i can't understand
this error show
but did not work show the error i can't understand
this error show

SoapCore errors

I keep getting this issue when I attempt to visit the wsdl page for a service I created in .Net Core 3.0
The request reached the end of the pipeline without executing the endpoint: 'SoapCore'. Please register the EndpointMiddleware using 'IApplicationBuilder.UseEndpoints(...)' if using routing.
SoapCore version: 1.1.0.1-beta
I have also tried version 1.0.0 with the same result
Code:
Configure Services Function
services.AddControllers();
services.AddSoapCore();
services.TryAddSingleton<MyService>();
services.AddMvc();
Configure Function
if (env.IsDevelopment() || env.IsEnvironment("local"))
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.UseSoapEndpoint<MyService>("/Service.svc", new BasicHttpBinding(), SoapSerializer.DataContractSerializer);
endpoints.MapControllers();
});
It appears the the path is case sensitive. Sorry all, and if anyone is as aloof as me, make sure when visiting your route that you case it just as you have it in code.

Categories

Resources