I'm trying to build a .Net Core 2 WebAPI/Angular hybrid app. I've followed a tutorial and successfully got it serving up the root of the client angular application, and routing within the client app works. However, if I try to navigate directly to a route (for example, "/register") using the browser's address bar, I get a 404. It seems like the WebAPI is attempting to process the request, and failing, as the controllers only have "/api/[controller]/[action]" routes. I'm using attribute-based routing. If it helps, here's my startup.cs file:
using System;
using System.Net;
using System.Text;
using AutoMapper;
using FluentValidation.AspNetCore;
using Io.BLL.Services.Impl.Auth;
using Io.BLL.Services.Interfaces.Auth;
using Io.Data;
using Io.Data.Entities;
using Io.Models.Auth;
using Io.Web.Extensions;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.IdentityModel.Tokens;
namespace Io.Web
{
public class Startup
{
public IConfiguration Configuration { get; }
private const string SecretKey = "iNivDmHr2E5Q6V3qvnqycprdRj1PVkH";
private readonly SymmetricSecurityKey _signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(SecretKey));
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<Context>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),
b =>
b.MigrationsAssembly("Io.Web")));
services.AddSingleton<IJwtFactory, JwtFactory>();
services.Configure<FacebookAuthSettings>(Configuration.GetSection(nameof(FacebookAuthSettings)));
services.TryAddTransient<IHttpContextAccessor, HttpContextAccessor>();
var jwtAppSettingOptions = Configuration.GetSection(nameof(JwtIssuerOptions));
services.Configure<JwtIssuerOptions>(options =>
{
options.Issuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)];
options.Audience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)];
options.SigningCredentials = new SigningCredentials(_signingKey, SecurityAlgorithms.HmacSha256);
});
var tokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)],
ValidateAudience = true,
ValidAudience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)],
ValidateIssuerSigningKey = true,
IssuerSigningKey = _signingKey,
RequireExpirationTime = false,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
};
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(configureOptions =>
{
configureOptions.ClaimsIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)];
configureOptions.TokenValidationParameters = tokenValidationParameters;
configureOptions.SaveToken = true;
});
services.AddAuthorization(options =>
{
options.AddPolicy("ApiUser", policy =>
policy.RequireClaim(JwtFactory.Rol, JwtFactory.ApiAccess));
});
var builder = services.AddIdentityCore<AppUser>(o =>
{
o.Password.RequireDigit = false;
o.Password.RequireLowercase = false;
o.Password.RequireUppercase = false;
o.Password.RequireNonAlphanumeric = false;
o.Password.RequiredLength = 6;
});
builder = new IdentityBuilder(builder.UserType, typeof(IdentityRole), builder.Services);
builder.AddEntityFrameworkStores<Context>().AddDefaultTokenProviders();
services.AddAutoMapper();
services.AddMvc().AddFluentValidation(fv => fv.RegisterValidatorsFromAssemblyContaining<Startup>());
services.AddScoped<IAuthService, AuthService>();
services.AddScoped<JwtIssuerOptions>();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
app.UseExceptionHandler(builder =>
{
builder.Run(
async context =>
{
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
var error = context.Features.Get<IExceptionHandlerFeature>();
if (error != null)
{
context.Response.AddApplicationError(error.Error.Message);
await context.Response.WriteAsync(error.Error.Message).ConfigureAwait(false);
}
});
});
app.UseAuthentication();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseMvc();
}
}
}
Thanks for your time and your help!
What I have tried:
CRUD USING .NET CORE 1.0, ANGULAR V2, WEBAPI[
^]