无法使用GET

时间:2018-02-01 22:58:24

标签: c# .net-core asp.net-core-mvc asp.net-core-webapi

我正在构建用于处理.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/"
    }
  }
}

2 个答案:

答案 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

参考Routing to Controller Actions