我正在构建用于处理.NET Core中身份信息的API,但每次尝试拨打电话时,我都会获得404.
当我四处寻找答案时,似乎没有任何明确的事情,因为发布的代码似乎很少。以下是我认为相关的所有内容。
控制器:
using Common.Extensions;
using Identity.Database.Contexts.Models;
using Identity.WebApi.Models;
using Identity.WebApi.Models.Tokens;
using Identity.WebApi.Services.Access;
using Identity.WebApi.Services.Accounts;
using Identity.WebApi.Services.Tokens;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.Security.Claims;
using System.Threading.Tasks;
using Controller = Microsoft.AspNetCore.Mvc.Controller;
using Get = Microsoft.AspNetCore.Mvc.HttpGetAttribute;
using Post = Microsoft.AspNetCore.Mvc.HttpPostAttribute;
using Route = Microsoft.AspNetCore.Mvc.RouteAttribute;
namespace Identity.WebApi.Controllers
{
[Route("api/[controller]")]
public class IdentityController : Controller
{
private readonly IApplicationUserService _userService;
private readonly IAccessService _accessService;
private readonly ITokenService _tokenService;
private readonly SignInManager<ApplicationUser> _signInManager;
public IdentityController(IApplicationUserService userService, IAccessService accessService, ITokenService tokenService, SignInManager<ApplicationUser> signInManager)
{
_userService = userService;
_accessService = accessService;
_tokenService = tokenService;
_signInManager = signInManager;
}
[Get]
[AllowAnonymous]
public string Index()
{
return new Dictionary<string,string>
{
{ "status", "live" }
}.Serialize();
}
[Post]
[Route("create")]
[AllowAnonymous]
public Task<ISet<IdentityResult>> Create(string user)
{
var decodedUser = DecodeUser(user);
var applicationUser = new ApplicationUser(new User
{
Id = Guid.NewGuid(),
Name = decodedUser.Username,
LastActive = DateTime.UtcNow
});
return _userService.Add(applicationUser, decodedUser.Password);
}
private (string Username, string Password) DecodeUser(string encodedUser)
{
var decodedUser = encodedUser.DecodeFrom64().Split(':');
return (Username: decodedUser[0], Password: decodedUser[1]);
}
private async Task<bool> CheckPasswordAsync(ApplicationUser user, string password)
=> await _signInManager.UserManager.CheckPasswordAsync(user, password);
}
}
初创公司:
using Identity.Database.Contexts;
using Identity.Database.Contexts.Access;
using Identity.Database.Contexts.Extensions;
using Identity.Database.Contexts.Models;
using Identity.WebApi.Models;
using Identity.WebApi.Services.Access;
using Identity.WebApi.Services.Accounts;
using Identity.WebApi.Services.Certs;
using Identity.WebApi.Services.Tokens;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System.Runtime.CompilerServices;
namespace Identity.WebApi
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton(new CertService(Configuration) as ICertService)
.AddTransient<IApplicationUserService, ApplicationUserService>()
.AddTransient<IApplicationRoleService, ApplicationRoleService>()
.AddTransient<IAccessService, AccessService>()
.AddTransient<ICertService, CertService>()
.AddTransient<ITokenService, TokenService>()
.AddTransient<ICrudDao<AppDbContext, Role>, RoleDao>()
.AddIdentities<ApplicationUser, ApplicationRole>()
.AddScoped<UserManager<ApplicationUser>, UserManager<ApplicationUser>>()
.AddScoped<SignInManager<ApplicationUser>, SignInManager<ApplicationUser>>()
.AddScoped<RoleManager<ApplicationRole>, RoleManager<ApplicationRole>>()
.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.Use(async (c, n) =>
{
await n();
if (c.Response.StatusCode == 404)
{
c.Request.Path = "/identity";
await n();
}
});
app.UseStaticFiles();
app.UseAuthentication();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc(r => { r.MapRoute(name: "default", template: "{controller=identity}/{action=Index}"); });
}
}
}
启动设置:
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:55048/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "api/identity/index",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"WebApplication1": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "api/identity/index",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://localhost:55048/"
}
}
}
答案 0 :(得分:2)
在控制器的顶部,你有:
[Route("api/[controller]")]
public class IdentityController : Controller
这意味着如果您的路线仅以api/
开头,那么它将与控制器匹配。此外,您的索引操作上没有任何额外的路由属性,因此它仅查找api/identity
。但是,您的启动设置与该部分不匹配,并且由于您没有与之匹配的任何其他路线,因此您将获得404。
app.UseMvc
中的默认路由不适用于此原因。
简单修复:在您的启动设置中将launchUrl
更改为api/identity
...然后关注@ Nkosi的answer
答案 1 :(得分:1)
如果使用属性路由,则示例中的api/identity/index
或[HttpGet]
与路由前缀不同,
Get
由于这似乎是一个不希望返回View的Web API,因此带有路由模板的[Get] //<-- Matches GET api/identity
[AllowAnonymous]
public IActionResult Index() {
var result = new Dictionary<string,string>
{
{ "status", "live" }
}.Serialize();
return Ok(result);
}
属性将是用于路由的选项
在构建REST API时,您很少需要在操作方法上使用
Http{Verb}
。最好使用更具体的[Route(...)]
来准确了解您的API支持的内容。 REST API的客户端应该知道哪些路径和HTTP谓词映射到特定的逻辑操作。
Http*Verb*Attributes